1> 將互斥機制的代碼實現重新敲一遍
代碼:
#include<myhead.h>int num=520;//臨界資源//1.創建互斥鎖
pthread_mutex_t fastmutex;//定義任務函數
void *task1(void *arg){printf("1111111\n");//3.臨界區上面獲取鎖資源(上鎖)pthread_mutex_lock(&fastmutex);num=1314;sleep(3);printf("task1:num = %d\n",num); //1314//4. 釋放鎖資源pthread_mutex_unlock(&fastmutex);
}void *task2(void *arg){printf("2222222\n");pthread_mutex_lock(&fastmutex);num++; //521sleep(1); //休眠時任務1執行到賦值語句printf("task2:num = %d\n",num);pthread_mutex_unlock(&fastmutex);
}int main(int argc, char const *argv[])
{//2.初始化互斥鎖pthread_mutex_init(&fastmutex,NULL);//線程創建pthread_t tid1,tid2;if(pthread_create(&tid1,NULL,task1,NULL)!=0){printf("tid1 create error\n");return 0;}if(pthread_create(&tid2,NULL,task2,NULL)!=0){printf("tid2 create error\n");return 0;}printf("tid1:%#lx, tid2:%#lx\n",tid1,tid2);//回收資源if(pthread_join(tid1,NULL)==0)printf("tid1回收成功\n");if(pthread_join(tid2,NULL)==0)printf("tid2回收成功\n");//5. 銷毀鎖資源pthread_mutex_destroy(&fastmutex);return 0;
}
結果:
2> 將無名信號量的代碼實現重新敲一遍
代碼:
#include<myhead.h>//創建無名信號了
sem_t sem;//定義生產者線程
void *task1(void *arg){printf("1111111\n");int num= 5;while(num--){//3.申請資源// sem_wait(&sem);sleep(1);printf("我生產了一輛車\n");//4.釋放資源sem_post(&sem);}pthread_exit(NULL);
}//定義消費者線程
void *task2(void *arg){printf("2222222\n");int num= 5;while(num--){//3.申請資源sem_wait(&sem);printf("我消費了一輛車\n");//4.釋放資源// sem_post(&sem);}pthread_exit(NULL);
}int main(int argc, char const *argv[])
{//初始化無名信號量sem_init(&sem,0,0);//第一個0:表示用于線程的同步//第二個0:表示初始資源為0//創建兩個線程,分別是生產者和消費者pthread_t tid1,tid2;if(pthread_create(&tid1,NULL,task1,NULL)!=0){printf("tid1 create error\n");return 0;}if(pthread_create(&tid2,NULL,task2,NULL)!=0){printf("tid2 create error\n");return 0;}printf("tid1:%#lx, tid2:%#lx\n",tid1,tid2);//回收資源if(pthread_join(tid1,NULL)==0)printf("tid1回收成功\n");if(pthread_join(tid2,NULL)==0)printf("tid2回收成功\n");//釋放無名信號量sem_destroy(&sem);return 0;
}
結果:
3> 將條件變量的代碼實現重新敲一遍
代碼:
#include<myhead.h>//1. 定義條件變量
pthread_cond_t cond;//11. 創建互斥鎖
pthread_mutex_t fastmutex;//定義生產者線程
void *task1(void *arg){int num= 5;while(num--){sleep(1);printf("%#lx:生產了一輛車\n",pthread_self());//3. 喚醒一個消費者pthread_cond_signal(&cond);}pthread_exit(NULL);
}//定義消費者線程
void *task2(void *arg){//33.臨界區上面獲取鎖資源(上鎖)pthread_mutex_lock(&fastmutex);//4. 進入等待隊列pthread_cond_wait(&cond,&fastmutex);printf("%#lx:消費了一輛車\n",pthread_self());//54. 釋放鎖資源pthread_mutex_unlock(&fastmutex);pthread_exit(NULL);
}int main(int argc, char const *argv[])
{//2. 初始化無名信號量pthread_cond_init(&cond,NULL);//22. 初始化互斥鎖pthread_mutex_init(&fastmutex,NULL);//創建2個線程,分別是生產者和消費者pthread_t tid1,tid2,tid3,tid4,tid5,tid6;if(pthread_create(&tid1,NULL,task1,NULL)!=0){printf("tid1 create error\n");return 0;}if(pthread_create(&tid2,NULL,task2,NULL)!=0){printf("tid2 create error\n");return 0;}if(pthread_create(&tid3,NULL,task2,NULL)!=0){printf("tid3 create error\n");return 0;}if(pthread_create(&tid4,NULL,task2,NULL)!=0){printf("tid4 create error\n");return 0;} if(pthread_create(&tid5,NULL,task2,NULL)!=0){printf("tid5 create error\n");return 0;}if(pthread_create(&tid6,NULL,task2,NULL)!=0){printf("tid6 create error\n");return 0;}printf("tid1:%#lx, tid2:%#lx, tid3:%#lx\ntid4:%#lx, tid5:%#lx, tid6:%#lx\n",tid1,tid2,tid3,tid4,tid5,tid6);//回收資源if(pthread_join(tid1,NULL)==0)printf("tid1回收成功\n");if(pthread_join(tid2,NULL)==0)printf("tid2回收成功\n");if(pthread_join(tid3,NULL)==0)printf("tid3回收成功\n");if(pthread_join(tid4,NULL)==0)printf("tid4回收成功\n");if(pthread_join(tid5,NULL)==0)printf("tid5回收成功\n");if(pthread_join(tid6,NULL)==0)printf("tid6回收成功\n");//5. 銷毀條件變量pthread_cond_destroy(&cond);//55. 銷毀鎖資源pthread_mutex_destroy(&fastmutex);return 0;
}
結果:
4> 將無名管道的代碼實現重新敲一遍
代碼:
#include<myhead.h>int main(int argc, char const *argv[])
{//創建管道文件,并返回該管道文件的文件描述符(最小位分配原則)int pipefd[2]={0};if(pipe(pipefd)==1)PRINT_ERR("");printf("pipedf[0]=%d,pipefd[1]=%d\n",pipefd[0],pipefd[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){//清空rbuf內容bzero(rbuf,sizeof(rbuf));//從管道文件中讀取數據read(pipefd[0],rbuf,sizeof(rbuf));//輸出rbuf的數據printf("父進程傳來的數據為:%s\n",rbuf);//對讀取的數據進行判斷if(strcmp(rbuf,"quit")==0)break;}//關閉管道的讀端close(pipefd[0]);exit(EXIT_SUCCESS); //退出進程}elsePRINT_ERR(""); return 0;
}
結果:
5> 將有名管道的代碼實現重新敲一遍
代碼:
#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;
}
#include<myhead.h>int main(int argc, char const *argv[])
{//打開管道文件int wfd=1;//以只寫的形式打開文件if((wfd=open("./myfifo",O_WRONLY))==-1)PRINT_ERR("");//定義容器char wbuf[128]="";while(1){bzero(wbuf,sizeof(wbuf)); //清空數組內容fgets(wbuf,sizeof(wbuf),stdin); //從終端輸入數據wbuf[strlen(wbuf)-1]=0;//將數據寫入管道文件中write(wfd,wbuf,strlen(wbuf));//對寫入的數據進行判斷if(strcmp(wbuf,"quit")==0)break;}return 0;
}
#include<myhead.h>int main(int argc, char const *argv[])
{//打開管道文件int wfd=1;//以只讀的形式打開文件if((wfd=open("./myfifo",O_RDONLY))==-1)PRINT_ERR("");//定義容器char rbuf[128]="";while(1){//清空rbuf內容bzero(rbuf,sizeof(rbuf));//將數據寫入管道文件中read(wfd,rbuf,sizeof(rbuf));//輸出rbuf的數據printf("父進程傳來的數據為:%s\n",rbuf);//對讀取的數據進行判斷if(strcmp(rbuf,"quit")==0)break;}return 0;
}
結果:
6> 使用有名管道完成兩個進程的相互通信(提示:可以使用多進程或多線程完成)
代碼:
管道文件創建
#include<myhead.h>int main(int argc, const char *argv[])
{//創建一個管道文件if(mkfifo("./myfifo1", 0664) == -1){perror("mkfifo1 error");return -1;}if(mkfifo("./myfifo2", 0664) == -1){perror("mkfifo2 error");return -1;}getchar(); //阻塞system("rm myfifo1");system("rm myfifo2");return 0;
}
線程:
#include<myhead.h>int main(int argc, char const *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("這里是1號機,請輸入>>>");fgets(wbuf, sizeof(wbuf), stdin);wbuf[strlen(wbuf)-1] = 0;//將數據寫入有名管道write(wfd, wbuf, strlen(wbuf));//判斷結果if(strcmp(wbuf,"quit") == 0)break;}//關閉文件close(wfd);
// wait(NULL); //阻塞回收子進程資源}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("\t\t\t\t\t1號機收到的數據為:%s\n", rbuf);//判斷結果if(strcmp(rbuf,"quit") == 0)break;}//關閉文件close(rfd);exit(EXIT_SUCCESS); //退出進程}elsePRINT_ERR(""); return 0;
}
#include<myhead.h>int main(int argc, char const *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("\t\t\t\t\t2號機收到的數據為:%s\n", rbuf);//判斷結果if(strcmp(rbuf,"quit") == 0)break;}//關閉文件close(rfd); // wait(NULL);// wait(NULL); //阻塞回收子進程資源}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("這里是2號機,請輸入>>>");fgets(wbuf, sizeof(wbuf), stdin);wbuf[strlen(wbuf)-1] = 0;//將數據寫入管道write(wfd, wbuf, strlen(wbuf));//判斷結果if(strcmp(wbuf,"quit") == 0)break;}//關閉文件close(wfd); exit(EXIT_SUCCESS); //退出進程}elsePRINT_ERR(""); return 0;
}
結果: