作业1:代码实现线程互斥机制
代码:
#include <myhead.h>//临界资源
int num=10;//创建一个互斥锁
pthread_mutex_t mutex;//任务一
void *task1(void *arg)
{//获取锁资源pthread_mutex_lock(&mutex);num=123;sleep(3);printf("task1:num=%d\n",num);//释放锁资源pthread_mutex_unlock(&mutex);//退出线程pthread_exit(NULL);
}
//任务二
void *task2(void *arg)
{//获取锁资源pthread_mutex_lock(&mutex);num++;sleep(1);printf("task2:num=%d\n",num);//释放锁资源pthread_mutex_unlock(&mutex);//退出线程pthread_exit(NULL);
}
/*************************主程序************************/
int main(int argc, const char *argv[])
{//初始化互斥锁pthread_mutex_init(&mutex,NULL);//创建两个线程pthread_t tid1,tid2;if(pthread_create(&tid1,NULL,task1,NULL) != 0){printf("create tid1 error\n");return -1;}if(pthread_create(&tid2,NULL,task2,NULL) != 0){printf("create tid1 error\n");return -1;}printf("tid1=%#lx tid2=%#lx\n",tid1,tid2);//回收资源pthread_join(tid1,NULL);pthread_join(tid2,NULL);//销毁互斥锁pthread_mutex_destroy(&mutex);return 0;
}
效果图:
作业2:代码实现无名信号量的线程同步机制
代码:
#include <myhead.h>//定义一个无名信号量
sem_t sem1;
sem_t sem2;
sem_t sem3;
//任务1
void *task1(void *arg)
{int num=4;while(num--){//申请资源sem_wait(&sem3);sleep(1);printf("A");fflush(stdout); //刷新缓冲区//释放资源sem_post(&sem1);}//退出线程pthread_exit(NULL);}
//任务2
void *task2(void *arg)
{int num=4;while(num--){//申请资源sem_wait(&sem1);sleep(1);printf("B");fflush(stdout); //刷新缓冲区//释放资源sem_post(&sem2);}//退出线程pthread_exit(NULL);}
//任务3
void *task3(void *arg)
{int num=4;while(num--){//申请资源sem_wait(&sem2);sleep(1);printf("C");fflush(stdout); //刷新缓冲区//释放资源sem_post(&sem3);}//退出线程pthread_exit(NULL);}
/*********************主程序********************/
int main(int argc, const char *argv[])
{//初始化无名信号量sem_init(&sem1,0,0);sem_init(&sem2,0,0);sem_init(&sem3,0,1);//创建三个线程pthread_t tid1,tid2,tid3;if(pthread_create(&tid1,NULL,task1,NULL) != 0){printf("create tid1 error\n");return -1;}if(pthread_create(&tid2,NULL,task2,NULL) != 0){printf("create tid2 error\n");return -1;}if(pthread_create(&tid3,NULL,task3,NULL) != 0){printf("create tid3 error\n");return -1;}//回收资源pthread_join(tid1,NULL);pthread_join(tid2,NULL);pthread_join(tid3,NULL);//销毁无名信号量sem_destroy(&sem1);sem_destroy(&sem2);sem_destroy(&sem3);puts("");return 0;
}
效果图:
作业3:代码实现条件变量的线程同步机制
代码:
#include <myhead.h>
//定义条件变量
pthread_cond_t cond;//定义互斥锁变量
pthread_mutex_t mutex;//生产者
void *task1(void *arg)
{int num=3;while(num--){sleep(1);printf("%#lx:摘了一个苹果\n",pthread_self());//唤醒一个进程pthread_cond_signal(&cond);}//退出线程pthread_exit(NULL);
}
//消费者
void *task2(void *arg)
{//获取锁资源pthread_mutex_lock(&mutex);//进入等待队列pthread_cond_wait(&cond,&mutex);printf("%#lx:吃了一个苹果\n",pthread_self());//释放锁资源pthread_mutex_unlock(&mutex);//退出进程pthread_exit(NULL);
}
int main(int argc, const char *argv[])
{//初始化条件变量pthread_cond_init(&cond,NULL);//初始化互斥锁变量pthread_mutex_init(&mutex,NULL);//创建生产者与消费者线程pthread_t tid1,tid2,tid3,tid4;if(pthread_create(&tid1,NULL,task1,NULL)!=0){printf("create tid1 error\n");return -1;}if(pthread_create(&tid2,NULL,task2,NULL)!=0){printf("create tid2 error\n");return -1;}if(pthread_create(&tid3,NULL,task2,NULL)!=0){printf("create tid3 error\n");return -1;}if(pthread_create(&tid4,NULL,task2,NULL)!=0){printf("create tid4 error\n");return -1;}//回收资源pthread_join(tid1,NULL);pthread_join(tid2,NULL);pthread_join(tid3,NULL);pthread_join(tid4,NULL);//销毁条件变量pthread_cond_destroy(&cond);//销毁互斥锁pthread_mutex_destroy(&mutex);return 0;
}
效果图:
作业4:代码实现无名管道的通信
代码:
#include <myhead.h>
int main(int argc, const char *argv[])
{//创建管道文件int pipefd[2]={0};if(pipe(pipefd)==-1){perror("pipe error");return -1;}//创建子进程pid_t pid=fork();if(pid>0){//父进程进行写操作//关闭管道读端close(pipefd[0]);char wbuf[128]="";while(1){//清空数组内容bzero(wbuf,sizeof(wbuf));//从终端输入数据fgets(wbuf,sizeof(wbuf),stdin);wbuf[strlen(wbuf)-1]='\0';//开始向管道文件中写入数据write(pipefd[1],wbuf,strlen(wbuf));//判断写入的数据if(strcmp(wbuf,"quit")==0){break;}}//关闭管道写端close(pipefd[1]);//等待回收子进程wait(NULL);}else if(pid==0){//子进程进行读操作//关闭管道写端close(pipefd[1]);char rbuf[128]="";while(1){//清空数组内容bzero(rbuf,sizeof(rbuf));//从管道文件中读取数据read(pipefd[0],rbuf,sizeof(rbuf));printf("从父进程传来的数据:%s\n",rbuf);//判断写入的数据if(strcmp(rbuf,"quit")==0){break;}}//关闭管道读端close(pipefd[0]);//退出子进程exit(EXIT_SUCCESS);}else{perror("pid error");return -1;}return 0;
}
效果图:
作业5:代码实现有名管道的通信
代码:
create.c:
#include <myhead.h>
int main(int argc, const char *argv[])
{//创建一个管道文件if(mkfifo("./myfifo",0664)==-1){perror("mkfifo error");return -1;}getchar(); //阻塞system("rm myfifo");return 0;
}
snd.c:
#include <myhead.h>int main(int argc, const char *argv[])
{//打开管道文件int wfd=-1;//以只写的形式打开管道文件if((wfd=open("./myfifo",O_WRONLY))==-1){perror("open error");return -1;}char wbuf[128]="";while(1){//从终端输入数据printf("请输入:"); fgets(wbuf,sizeof(wbuf),stdin);wbuf[strlen(wbuf)-1]='\0';//将数据写入管道文件write(wfd,wbuf,strlen(wbuf));//结束输入的条件if(strcmp(wbuf,"quit")==0){break;}}//关闭文件close(wfd);return 0;
}
rec.c:
#include <myhead.h>
int main(int argc, const char *argv[])
{//打开管道文件int rfd=-1;//以只读形式打开文件if((rfd=open("./myfifo",O_RDONLY))==-1){perror("open error");return -1;}char rbuf[128]="";while(1){//清空数组bzero(rbuf,sizeof(rbuf));//从管道读取数据read(rfd,rbuf,sizeof(rbuf));//输出结果printf("收到的数据为:%s\n",rbuf);//退出条件if(strcmp(rbuf,"quit")==0){break;}}//关闭文件close(rfd);return 0;
}
效果图:
作业6:使用有名管道完成两个进程的相互通信
(提示:可以使用多进程或多线程完成)
代码:
create.c:
#include <myhead.h>
int main(int argc, const char *argv[])
{//创建两个管道文件if(mkfifo("./myfifo1",0664)==-1){perror("mkfifo error");return -1;}if(mkfifo("./myfifo2",0664)==-1){perror("mkfifo error");return -1;}getchar(); //阻塞system("rm myfifo1");system("rm myfifo2");return 0;
}
snd.c:
#include <myhead.h>int main(int argc, const char *argv[])
{//创建一个进程pid_t pid=fork();if(pid>0){//父进程发送数据//打开管道文件int wfd=-1;//以只写的形式打开管道文件if((wfd=open("./myfifo1",O_WRONLY))==-1){perror("open error");return -1;}char wbuf[128]="";while(1){//从终端输入数据printf("请输入:"); fgets(wbuf,sizeof(wbuf),stdin);wbuf[strlen(wbuf)-1]='\0';//将数据写入管道文件write(wfd,wbuf,strlen(wbuf));//结束输入的条件if(strcmp(wbuf,"quit")==0){break;}}//关闭文件close(wfd);}else if(pid==0){//子进程接收数据//打开管道文件int rfd=-1;//以只读形式打开文件if((rfd=open("./myfifo2",O_RDONLY))==-1){perror("open error");return -1;}char rbuf[128]="";while(1){//清空数组bzero(rbuf,sizeof(rbuf));//从管道读取数据read(rfd,rbuf,sizeof(rbuf));//输出结果printf("收到的数据为:%s\n",rbuf);//退出条件if(strcmp(rbuf,"quit")==0){break;}}//关闭文件close(rfd);}else{perror("pid error");return -1;}return 0;
}
rec.c:
#include <myhead.h>int main(int argc, const char *argv[])
{//创建一个进程pid_t pid=fork();if(pid>0){//父进程接收数据//打开管道文件int rfd=-1;//以只读形式打开文件if((rfd=open("./myfifo1",O_RDONLY))==-1){perror("open error");return -1;}char rbuf[128]="";while(1){//清空数组bzero(rbuf,sizeof(rbuf));//从管道读取数据read(rfd,rbuf,sizeof(rbuf));//输出结果printf("收到的数据为:%s\n",rbuf);//退出条件if(strcmp(rbuf,"quit")==0){break;}}//关闭文件close(rfd);}else if(pid==0){//子进程发送数据//打开管道文件int wfd=-1;//以只写的形式打开管道文件if((wfd=open("./myfifo2",O_WRONLY))==-1){perror("open error");return -1;}char wbuf[128]="";while(1){//从终端输入数据printf("请输入:"); fgets(wbuf,sizeof(wbuf),stdin);wbuf[strlen(wbuf)-1]='\0';//将数据写入管道文件write(wfd,wbuf,strlen(wbuf));//结束输入的条件if(strcmp(wbuf,"quit")==0){break;}}//关闭文件close(wfd);}else{perror("pid error");return -1;}return 0;
}
效果图: