问题描述:多线程
公共汽车上,司机和售票员的活动分别是:
司机的活动:启动车辆;正常行车;到站停车。
售票员的活动:关车门;售票;开车门。函数
在汽车不断的到站、停站、行驶过程当中,用信号量和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); } }