linux 環境下使用信號量實現司機售票員進程同步,線程同步問題

問題描述:多線程

公共汽車上,司機和售票員的活動分別是:
司機的活動:啓動車輛;正常行車;到站停車。
售票員的活動:關車門;售票;開車門。函數

在汽車不斷的到站、停站、行駛過程當中,用信號量和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);
        }
}

相關文章
相關標籤/搜索