作業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;
}
效果圖: