問題描述:多線程
公共汽車上,司機和售票員的活動分別是:
司機的活動:啓動車輛;正常行車;到站停車。
售票員的活動:關車門;售票;開車門。函數
在汽車不斷的到站、停站、行駛過程當中,用信號量和P,V操做實現它們的同步。post
問題解決;線程
咱們可使用兩個信號量來實現司機與售票員間的同步,具體實現形式以下:code
司機進程:進程
司機開車;ip
v(s2);get
p(s1);同步
汽車離站;it
售票員進程:
售票員售票;
p(s2);
售票員開車門;
乘客上下車;
售票員關車門;
v(s1);
多線程實現同步:
#include<stdio.h> #include<pthread.h> #include<semaphore.h> sem_t semid1,semid2; void* driver() { while(1) { printf("\n"); printf("driver開車\n");
sem_post(&semid1); sem_wait(&semid2); printf("driver離站\n"); } } void* passenger() { while(1) { printf("conductor售票\n"); sem_wait(&semid1); printf("conductor開車門\n"); printf("passenger上下車\n"); printf("conductor關車門\n"); sem_post(&semid2); } } int main() { sem_init(&semid1,0,0); sem_init(&semid2,0,0); pthread_t tid1,tid2; pthread_create(&tid1,0,driver,0); pthread_create(&tid2,0,passenger,0); pthread_join(tid1,(void**)0); pthread_join(tid2,(void**)0); return 0; }
多進程實現同步:
#include<stdio.h> #include<unistd.h> #include<stdlib.h> #include<sys/ipc.h> #include<sys/sem.h> int semid1,semid2; //定義兩個信號量 void v1(int semid1); void v2(int semid2); void p1(int semid1); void p2(int semid2); void conductor(); void driver(); //2.1定義semun共用體 union semun { int val; struct semid_ds *buf; unsigned short *array; struct seminfo *__buf; }; int main() { key_t key1,key2;定義信號量的key值 //int semid1,semid2; //2.2定義信號量初始值 union semun v1,v2; int r1,r2; //struct sembuf op1[1],op[2]; //1.建立信號量 key1=ftok(".",36); key2=ftok(".",98); if(key1==-1) { printf("key1 get erro:%m\n"); exit(-1); } if(key2==-1) { printf("key2 get erro:%m\n"); exit(-1); } //獲得信號量 semid1=semget(key1,1,IPC_CREAT|IPC_EXCL|0666); semid2=semget(key2,1,IPC_CREAT|IPC_EXCL|0666); //semid1=semget(key1,1,0); //semid2=semget(key2,1,0); if(semid1==-1) { printf("semid1 get erro:%m\n"); exit(-1); } if(semid2==-1) { printf("semid2 get erro:%m\n"); exit(-1); } //printf("semid1:%d\n",semid1); //printf("semid2:%d\n",semid2); //2.初始化信號量爲0 v1.val=0; v2.val=0; r1=semctl(semid1,0,SETVAL,v1); r2=semctl(semid2,0,SETVAL,v2); if(r1==-1) { printf("r1 get erro:%m\n"); exit(-1); } if(r2==-1) { printf("r2 get erro:%m\n"); exit(-1); } if(fork()>0) //父進程 { driver(); } else //子進程 { conductor(); } //4.刪除信號量 semctl(semid1,0,IPC_RMID); semctl(semid2,0,IPC_RMID); return 0; } void p1(int semid1) { struct sembuf op1[1]; op1[0].sem_num=0; op1[0].sem_op=-1;//p進行-1操做 op1[0].sem_flg=0; semop(semid1,op1,1); } void p2(int semid2) { struct sembuf op2[1]; op2[0].sem_num=0; op2[0].sem_op=-1;//p進行-1操做 op2[0].sem_flg=0; semop(semid2,op2,1); } void v1(int semid1) { struct sembuf op1[1]; op1[0].sem_num=0; op1[0].sem_op=1;//v進行+1操做 op1[0].sem_flg=0; semop(semid1,op1,1); } void v2(int semid2) { struct sembuf op2[1]; op2[0].sem_num=0; op2[0].sem_op=1;//v進行+1操做 op2[0].sem_flg=0; semop(semid2,op2,1); } void driver()//司機操做函數 { while(1) { printf("driver開車\n"); v2(semid2); p1(semid1); printf("driver離站\n"); sleep(1); } } void conductor()//售票員操做函數 { while(1) { printf("conductor售票\n"); p2(semid2); printf("conductor開車門\n"); printf("passenger上下車\n"); printf("conductor關車門\n"); v1(semid1); sleep(1); } }