1> 将互斥机制代码重新实现一遍
#include<myhead.h>char buf[128]; //临界资源pthread_mutex_t mutex; //创建锁资源//分支线程
void* task(void* arg)
{while(1){//获取锁资源pthread_mutex_lock(&mutex);printf("这里是分支线程:%s\n",buf);strcpy(buf,"你好!!!!");//释放锁资源pthread_mutex_unlock(&mutex);}
}int main(int argc, const char *argv[])
{pthread_t tid;//定义线程IDpthread_mutex_init(&mutex,NULL);//初始化锁资源if(pthread_create(&tid,NULL,task,NULL)!=0){perror("create error");return -1;}//主线程while(1){//获取锁资源pthread_mutex_lock(&mutex);printf("这里是主线程:buf=%s\n",buf);strcpy(buf,"hello???");//释放锁资源pthread_mutex_unlock(&mutex);}//回收线程资源pthread_join(tid,NULL);//消毁锁资源pthread_mutex_destroy(&mutex);return 0;
}
2> 将同步机制代码重新实现一遍
#include<myhead.h>
sem_t sem;
void*skit1(void * arg)
{while(1){sleep(2);printf("我工作了一天\n");//释放资源sem_post(&sem);}
}void*skit2(void*arg)
{while(1){sem_wait(&sem);//申请资源printf("又赚了三百\n");}
}
int main(int argc, const char *argv[])
{pthread_t tid1,tid2;sem_init(&sem,0,0);//初始化无名信号量,第一个0表示线程通信,第二个表示value初始值0;//创建支线程1if(pthread_create(&tid1,NULL,skit1,NULL)!=0){printf("pthread error");return -1;}//创建支线程2if(pthread_create(&tid2,NULL,skit2,NULL)!=0){printf("pthread error");return -1;}pthread_join(tid1,NULL);pthread_join(tid2,NULL);sem_destroy(&sem);return 0;
}
3> 使用三个线程完成两个文件的拷贝,线程1完成拷贝前一半,线程2完成拷贝后一半,主线程回收两个分支线程的资源
#include <myhead.h>
//创建无名信号量
sem_t sem;
//创建文件相关结构体
typedef struct File
{const char *src_file;const char *dest_file;off_t start;off_t end;
} * fileStruct;//获取文件字符长度
int length(const char *srcfile, const char *destfile)
{//打开原文件和目标文件int srcfd = open(srcfile, O_RDONLY);int destfd = open(destfile, O_WRONLY | O_CREAT | O_TRUNC, 0664);if (srcfd == -1 || destfd == -1){perror("open file error");return -1;}//光标从头到尾,返回字符个数int len = lseek(srcfd, 0, SEEK_END);//关闭文件close(srcfd);close(destfd);return len;
}
//文件拷贝函数
int copy_file(const char *srcfile, const char *destfile, int start, int end)
{int srctd, desttd;//打开原文件和目标文件int srcfd = open(srcfile, O_RDONLY);//在计算字符长度函数中已经创建过文件,所以只需要写int destfd = open(destfile, O_WRONLY|O_TRUNC);if (srcfd == -1 || destfd == -1){perror("open file error");return -1;}//重新定位光标到文件开头lseek(srcfd, start, SEEK_SET);lseek(destfd, start, SEEK_SET);//搬运工char buffer[1] = "";int res_read = 0;int res_write = 0;//拷贝字符到创建的文件中去//当前光标位置在目标光标位置前,则写入while (start < end){res_read = read(srcfd, buffer, sizeof(buffer));if (res_read <= 0)break;res_write = write(destfd, buffer, res_read);start += res_write;}//关闭文件close(srcfd);close(destfd);
}
void *task1(void *arg)
{fileStruct fStruct = (fileStruct)arg;copy_file(fStruct->src_file, fStruct->dest_file, fStruct->start, fStruct->end);// 完成前一半拷贝,释放资源sem_post(&sem);free(fStruct); // 释放传入的结构体内存printf("线程1完成前半部分拷贝");
}
void *task2(void *arg)
{//等待线程tid1写入前一半,然后申请sem_wait(&sem);fileStruct fStruct=(fileStruct)arg;copy_file(fStruct->src_file,fStruct->dest_file,fStruct->start,fStruct->end);free(fStruct);printf("线程2完成前后部分拷贝");
}
int main(int argc, char const *argv[])
{//定义两个线程pthread_t tid1, tid2;//初始化无名信号量,要在创建线程前初始化sem_init(&sem, 0, 0);//获取返回的字符长度int len = length(argv[1], argv[2]);//创建结构体变量,并赋值fileStruct arg1 = (fileStruct)malloc(sizeof(struct File));fileStruct arg2 = (fileStruct)malloc(sizeof(struct File));arg1->src_file = argv[1];arg1->dest_file = argv[2];arg1->start = 0;arg1->end = len / 2;arg2->src_file = argv[1];arg2->dest_file = argv[2];arg2->start = len / 2;arg2->end = len;if (pthread_create(&tid1, NULL, task1, arg1) != 0){printf("create pthread1 error\n");return -1;}if (pthread_create(&tid2, NULL, task2, arg2) != 0){printf("create pthread2 error\n");return -1;}//线程资源回收pthread_join(tid1, NULL);pthread_join(tid2, NULL);//销毁无名信号量sem_destroy(&sem);return 0;
}
4> 使用三个线程完成:线程1输出字符'A',线程2输出字符'B',线程3输出字符'C',要求输出结果为:ABCABCABCABCABC...
#include <myhead.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);//为了顺利进入第一个线程必须要初始化为1sem_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);}
}