OS實驗二 執行緒同步與通訊
阿新 • • 發佈:2018-12-12
1 實驗目的與要求
1、掌握Linux下執行緒的概念;
2、瞭解Linux執行緒同步與通訊的主要機制;
3、通過訊號燈操作實現執行緒間的同步與互斥。
2 實驗內容
通過Linux多執行緒與訊號燈機制,設計並實現計算機執行緒與I/O執行緒共享緩衝區的同步與通訊。
程式要求:兩個執行緒,共享公共變數a
執行緒1負責計算(1到100的累加,每次加一個數)
執行緒2負責列印(輸出累加的中間結果)
#include <stdio.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h> #include <pthread.h> union semun { int val; /* value for SETVAL */ struct semid_ds *buf; /* buffer for IPC_STAT, IPC_SET */ unsigned short *array; /* array for GETALL, SETALL */ struct seminfo *__buf; /* buffer for IPC_INFO */ }; int i=0,sum=0; int semid;//訊號量集合首地址 pthread_t p1,p2; union semun arg; void P(int semid, int index); void V(int semid, int index); /***對訊號量陣列index編號的訊號量做P操作***/ void P(int semid, int index){ struct sembuf sem={index,-1,0}; semop(semid,&sem,1); } /***對訊號量陣列index編號的訊號量做V操作***/ void V(int semid, int index){ struct sembuf sem={index,+1,0}; semop(semid,&sem,1); } /*執行緒一*/ void thread_1(void){ for(;i<=100;i++){ P(semid,0); printf("This is a pthread_1.\ni=%d\n",i); sum+=i; V(semid,1); } return; } /*執行緒二*/ void thread_2(void){ for(;;){ P(semid,1); printf("This is a pthread_2.\nsum=%d\n",sum); if(i==101)return; V(semid,0); } } int main(){ int key ; int ret; key=ftok("/tmp", 0x66 ) ; if(key<0){ perror("ftok key error") ; return -1 ; } /***建立兩個訊號量***/ semid=semget(key,2,IPC_CREAT|0666); if(semid==-1){ perror("create semget error"); return ; } /***對0號訊號量設定初始值***/ arg.val=1; ret=semctl(semid,0,SETVAL,arg);//訊號量semid【0】為1 arg.val=0; ret =semctl(semid,1,SETVAL,arg);//訊號量semid【1】為0 if (ret < 0 ){ perror("ctl sem error"); semctl(semid,0,IPC_RMID,arg); return -1 ; } /*建立執行緒一*/ ret=pthread_create(&p1,NULL,(void *) thread_1,NULL); if(ret!=0) { printf("Create pthread error!\n"); return -1; } /*建立執行緒二*/ ret=pthread_create(&p2,NULL,(void *) thread_2,NULL); if(ret!=0) { printf("Create pthread error!\n"); return -1; } /*等待執行緒結束*/ pthread_join(p1,NULL); pthread_join(p2,NULL); /***刪除訊號量***/ semctl(semid,0,IPC_RMID,arg); semctl(semid,1,IPC_RMID,arg); return 0; }
執行結果: