问题描述:
公共汽车上,司机和售票员的活动分别是:
司机的活动:启动车辆;正常行车;到站停车。
售票员的活动:关车门;售票;开车门。
在汽车不断的到站、停站、行驶过程中,用信号量和P,V操作实现它们的同步。
问题解决;
我们可以使用两个信号量来实现司机与售票员间的同步,具体实现形式如下:
司机进程:
司机开车;
v(s2);
p(s1);
汽车离站;
售票员进程:
售票员售票;
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);
}
}