IO线程day5

多线程同步与文件拷贝实践
本文通过两个示例介绍了多线程编程在字符串操作和文件拷贝中的应用。第一个例子展示了如何使用互斥锁实现线程安全的字符串倒置与打印,确保不出现乱序。第二个例子中,两个线程分别拷贝文件的前半部分和后半部分,避免使用sleep和额外标志,确保完整拷贝文件。

题目1

定义一个全局变量,char str[] = “123456”,要求定义两个线程:线程A, 线程B

  1. 要求A线程循环打印全局字符串str;

  2. 要求B线程循环倒置全局字符串str:将str中的内容倒置为"654321",再倒置为"123456"…

    注意:是倒置不是倒着打印

  3. 要求A线程打印出的str字符串内容为:123456或者654321。

    不允许出现乱序,例如:623451 653451,,,

代码

头文件和全局变量

#include<stdio.h>
#include<pthread.h>
#include<unistd.h>
#include<string.h>

#define PER(per) {		fprintf(stderr,"line:%d  ",__LINE__);\
						perror(per);\
						return -1;}


//全局变量
char str[]="123456";
pthread_mutex_t mutex; //定义互斥锁

倒置函数

//倒置函数
void* func(void* arg )
{
	while(1)
	{

		pthread_mutex_lock(&mutex);  //上锁
		
		int i=strlen(str);
		while(i>strlen(str)/2)
		{
			char temp=str[i-1];
			str[i-1]=str[strlen(str)-i];
			str[strlen(str)-i]=temp;
			i--;
		}
		
		pthread_mutex_unlock(&mutex); //解锁

	}
	pthread_exit(NULL);

}

show函数

//show函数
void* show(void* arg)
{
	while(1)
	{
		pthread_mutex_lock(&mutex);   //上锁
		
		printf("a:%s\n",str);
//		sleep(1);

		pthread_mutex_unlock(&mutex); //解锁


	}
	pthread_exit(NULL);


}

主函数

int main(int argc, const char *argv[])
{

	if(pthread_mutex_init(&mutex,NULL)!=0)  //创建互斥锁,并初始化
	{
		PER("pthread_mutex_init")
	}

	//创建子进程
	printf("准备创建子进程\n");
	pthread_t tid1,tid2;
	
	if(pthread_create(&tid1,NULL,func,NULL)!=0)     //倒置进程
	{
		PER("pthread_create")
	}

	if(pthread_create(&tid2,NULL,show,NULL)!=0)  //打印进程
	{
		PER("pthread_create")
	}

	pthread_join(tid1,NULL);
	pthread_join(tid2,NULL);

	pthread_mutex_destroy(&mutex); //销毁锁


	return 0;
}

题目2

  1. 要求用两个线程拷贝一张图片,A线程拷贝前半部分,B线程拷贝后半部分

不允许使用sleep函数,不允许使用flag

代码

头文件和全局变量

#include<stdio.h>
#include<pthread.h>
#include<unistd.h>
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>

#define PER(per) {		fprintf(stderr,"line:%d  ",__LINE__);\
						perror(per);\
						return -1;}


#define PER1(per) {		fprintf(stderr,"line:%d  ",__LINE__);\
						perror(per);\
						return NULL;}



//全局变量
char str[]="123456";
pthread_mutex_t mutex; //定义互斥锁
off_t size;             //文件大小
int fd;
int fd_r;

拷贝前半部分

//拷贝前半部分
void* head(void* arg )
{
	pthread_mutex_lock(&mutex);  //上锁
	char c;	
	
	off_t x=lseek(fd,0,SEEK_SET); //回到写文件开头

	if(x==(off_t)-1)
	{
		PER1("lseek")
	}


	x=lseek(fd_r,0,SEEK_SET); //回到读文件开头
	if(x==(off_t)-1)
	{
		PER1("lseek")
	}


	while(1)
	{
		ssize_t	res=read(fd_r,&c,sizeof(c));
		if(res<=0)
		{
			if(res==0)
				break;
			if(res<0)
			{
				PER1("read")
			}
		}
		if(write(fd,&c,sizeof(c))==EOF)
		{
			PER1("write")
		}


		x=lseek(fd_r,0,SEEK_CUR); //确认写到了哪里
		if(x==(off_t)-1)
		{
			PER1("lseek")
		}
		
		if(x==size/2)
		{
			break;
		}
		
	}
	
	pthread_mutex_unlock(&mutex); //解锁
	pthread_exit(NULL);

}

拷贝后半部分

//拷贝后半部分
void* tail(void* arg)
{
	pthread_mutex_lock(&mutex);  //上锁
	char c;	

	off_t x=lseek(fd,size/2,SEEK_SET);//回到文件中间
	if(x==(off_t)-1)
	{
		PER1("lseek")
	}


	 x=lseek(fd_r,size/2,SEEK_SET); //回到文件中间
	if(x==(off_t)-1)
	{
		PER1("lseek")
	}


	while(1)
	{
		ssize_t	res=read(fd_r,&c,sizeof(c));
		if(res<=0)
		{
			if(res==0)
				break;
			if(res<0)
			{
				PER1("read")
			}
		}
		if(write(fd,&c,sizeof(c))==EOF)
		{
			PER1("write")
		}
		
	}
	
	pthread_mutex_unlock(&mutex); //解锁
	pthread_exit(NULL);
}

主函数

int main(int argc, const char *argv[])
{

	if(pthread_mutex_init(&mutex,NULL)!=0)  //创建互斥锁,并初始化
	{
		PER("pthread_mutex_init")
	}
	//打开源文件,以读的方式
	fd_r=open(argv[1],O_RDONLY);
	if(fd_r==EOF)
	{
		PER("open")
	}
	
	umask(0);
	//打开目标文件,以写的方式
	fd=open(argv[2],O_RDWR|O_CREAT|O_TRUNC,0644);
	if(fd==EOF)
	{
		PER("open")
	}

	//获取文件的大小
	off_t size=lseek(fd_r,0,SEEK_END);
	if(size==(off_t)-1)
	{
		PER("lseek")
	}



	//创建子进程
	printf("准备创建子进程\n");
	pthread_t tid1,tid2;
	
	if(pthread_create(&tid1,NULL,head,NULL)!=0)     //拷贝前半部分
	{
		PER("pthread_create")
	}
	

	if(pthread_create(&tid2,NULL,tail,NULL)!=0)  //拷贝后半部分
	{
		PER("pthread_create")
	}

	pthread_join(tid1,NULL);
	pthread_join(tid2,NULL);

	pthread_mutex_destroy(&mutex); //销毁锁
	
	close(fd);
	close(fd_r);

	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值