思维导图
将互斥机制代码重新实现一遍
#include
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
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
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
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);
}
}