day5:线程

思维导图

将互斥机制代码重新实现一遍

#include <head.h>
int a=0;//全局变量,临界资源
pthread_mutex_t mutex;//定义互斥锁
void *task(void *argc)//子线程任务
{
	while(1)
	{
		pthread_mutex_lock(&mutex);//上锁
		a=10;
		printf("a=%d",a);
		pthread_mutex_unlock(&mutex);//开锁
	}
}
int main(int argc, const char *argv[])
{
	//创建子线程
	pthread_t tid;
	if(pthread_create(&tid,NULL,task,NULL)!=0)
	{
		printf("create error\n");
		return -1;
	}
	while(1)
	{
		pthread_mutex_lock(&mutex);//上锁
		a=100;
		printf("a=%d",a);
		pthread_mutex_unlock(&mutex);//开锁
	}
	return 0;
}


将同步机制代码重新实现一遍

#include <head.h>
int a=0;//全局变量
sem_t sem;//定义无名信号量
void *task(void *arg)//子线程
{
	while(1)
	{
		sem_wait(&sem);//设置查询注定他不能第一个执行
		a=10;
		printf("a=%d",a);
	}
}
int main(int argc, const char *argv[])
{
	sem_init(&sem,0,0);//无名信号量初始化为0
	pthread_t tid;//创建子线程
	if(tid=pthread_create(&tid,NULL,task,NULL)!=0)
	{
		printf("create error\n");
		return -1;
	}
	while(1)//主线程
	{
		//不设置查询直接进入使用,注定第一次使用
		a=100;
		printf("a=%d",a);
		sem_post(&sem);//结束后将sem+1以便子线程查询成功并执行
	}
	return 0;
}


使用三个线程完成两个文件的拷贝,线程1完成拷贝前一半,线程2完成拷贝后一半,主线程回收两个分支线程的资源

#include <head.h>
typedef struct node//创建结构体用于创建线程时函数指针中的参数传递
{
	int length;
	const char *src;
	const char *dest;
}sake;
//函数声明
int size();
void copy(const char *file1,const char *file2,int start,int len);
void *task1(void *arg);
void *task2(void *arg);
int main(int argc, const char *argv[])
{
	//先计算出文件大小
	int len=size(argv[1],argv[2]);
	//在线程函数中的参数需要两个文件和大小,所以要定义结构体传参
	//定义结构体并初始化
	sake *file=(sake*)malloc(sizeof(struct node));
	file->length=len;
	file->src=argv[1];
	file->dest=argv[2];
	//建立两个线程
	pthread_t tid1,tid2;
	if(pthread_create(&tid1,NULL,task1,file)!=0)
	{
		printf("error1\n");
		return -1;
	}
	if(pthread_create(&tid2,NULL,task2,file)!=0)
	{
		printf("error2\n");
		return -1;
	}

	//收拾工作
	pthread_join(tid1,NULL);
	pthread_join(tid2,NULL);
	//释放结构体内存
	free(file);
	file=NULL;
	return 0;
}
int size(const char *file1,const char *file2)
{
	//利用文件描述符操作文件
	int fd1,fd2;
	if((fd1=open(file1,O_RDONLY))==0)
	{
		perror("");
		return -1;
	}
	if((fd2=open(file2,O_WRONLY|O_CREAT,0664))==0)
	{
		perror("");
		return -1;
	}
	//使用lseek函数计算文件大小
	int len=lseek(fd1,0,SEEK_END);
	close(fd1);
	close(fd2);
	return len;
}
void copy(const char *file1,const char *file2,int start,int len)
{
	//创建文件描述符
	int fd1,fd2;
	if((fd1=open(file1,O_RDONLY))==0)
	{
		perror("");
		return;
	}
	if((fd2=open(file2,O_WRONLY))==0)
	{
		perror("");
		return;
	}
	//定位光标
	lseek(fd1,start,SEEK_SET);
	lseek(fd2,start,SEEK_SET);
	char buf[10];//搬运工
	int sum=0;//用于累计搬运的大小,作为循环出口
	while(1)
	{
		int res=read(fd1,buf,sizeof(buf));
		sum+=res;
		if(sum>=len)
		{
			write(fd2,buf,res-sum+len);//当搬运大小到达制定大小的时候需要最后一次写入
			break;
		}
		write(fd2,buf,res);
	}
	close(fd1);
	close(fd2);
}
void *task1(void *arg)
{
	//从0开始拷贝到len/2处
	copy(((sake*)arg)->src,((sake*)arg)->dest,0,((sake*)arg)->length/2);	
}
void *task2(void *arg)
{
	//从len/2处到文件结尾
	copy(((sake*)arg)->src,((sake*)arg)->dest,((sake*)arg)->length/2,((sake*)arg)->length-((sake*)arg)->length/2);
}


使用三个线程完成:线程1输出字符A',线程2输出字符B',线程3输出字符'C',要求输出结果为:ABCABCABCABCABC

#include <head.h>
sem_t sem1,sem2,sem3;//三个线程分别的无名信号量
//函数声明
void *task1(void *arg);
void *task2(void *arg);
void *task3(void *arg);
int main(int argc, const char *argv[])
{
	//无名信号量初始化
	sem_init(&sem1,0,1);//为了顺利进入第一个线程必须要初始化为1
	sem_init(&sem2,0,0);
	sem_init(&sem3,0,0);
	//定义三个线程
	pthread_t tid1,tid2,tid3;
	if(pthread_create(&tid1,NULL,task1,NULL)!=0)
	{
		printf("error1\n");
		return -1;
	}
	if(pthread_create(&tid2,NULL,task2,NULL)!=0)
	{
		printf("error2\n");
		return -1;
	}
	if(pthread_create(&tid3,NULL,task3,NULL)!=0)
	{
		printf("error3\n");
		return -1;
	}
	//收尸
	pthread_join(tid1,NULL);
	pthread_join(tid2,NULL);
	pthread_join(tid3,NULL);
	return 0;
}
void *task1(void *arg)
{
	while(1)
	{
		sem_wait(&sem1);//询问当前任务的无名信号量(下同)
		putchar('A');
		fflush(stdout);//刷新缓冲区(下同)
		sleep(1);
		sem_post(&sem2);//将下一个任务的无名信号量改变为1(下同)
	}
}
void *task2(void *arg)
{
	while(1)
	{
		sem_wait(&sem2);
		putchar('B');
		fflush(stdout);
		sleep(1);
		sem_post(&sem3);
	}
}
void *task3(void *arg)
{
	while(1)
	{
		sem_wait(&sem3);
		putchar('C');
		fflush(stdout);
		sleep(1);
		sem_post(&sem1);
	}
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值