【Linux】信号量

一 、使得A B 两个进程有序的输出。

a进程 开始输出A 结束输出A
b进程 开始输出B 结束输出B


正确输出:
AABBAABBAABBAABBAABB


思考:
要使两个进程在打印的时候不出现交叉打印,进行加锁操作设置一个信号量即可,让a进行打印完换b进程进行打印。

进行a.c b.c sem.c sem.h 的编写

a.c

  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 #include<unistd.h>
  4 #include<string.h>
  5 #include<assert.h>
  6 #include"sem.h"
  7 int main ()
  8 {
  9     sem_init();
 10     for(int i = 0 ;i<5;i++)
 11     {
 12         sem_p();
 13        printf("A");
 14        fflush(stdout);
 15        int n = rand()%3;
 16        sleep(n);
 17        printf("A");
 18        fflush(stdout);
 19         sem_v();
 20        n = rand()%3;
 21        sleep(n);
 22 
 23     }
 24 
 25     sem_destory();
 26     sleep(10);
 27 }
 28 
              

b.c

  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 #include<unistd.h>
  4 #include<string.h>
  5 #include<assert.h>
  6 #include"sem.h"
  7 int main ()
  8 {
  9     sem_init();
 10     for(int i = 0 ;i<5;i++)
 11     {
 12         sem_p(); //加锁
 13        printf("B");
 14        fflush(stdout);
 15        int n = rand()%3;
 16        sleep(n);
 17        printf("B");
 18        fflush(stdout);
 19         sem_v();//解锁
 20        n = rand()%3;
 21        sleep(n);
 22 
 23     }
 24 }
 25 


sem.c

  1 #include"sem.h"
  2 
  3 static int semid  = -1;
  4 
  5 void sem_init()
  6 {
  7   semid = semget((key_t)1234,1,IPC_CREAT|IPC_EXCL|0600);
  8   if(semid == -1)
  9   {
 10       semid = semget((key_t)1234,1,0600);
 11       if( semid == -1)
 12       {
 13           printf("semgrt err\n");
 14           return ;
 15       }
 16   }
 17   else
 18   {
 19       union semun a;
 20       a.val = 1;
 21 
 22       if(semctl(semid,0,SETVAL,a) == -1)
 23       {
 24           printf("semcti err\n");
 25       }
 26   }
 27 
 28 }
 29 void sem_p()
 30 {
 31     struct sembuf buf;
 32     buf.sem_num = 0;
 33     buf.sem_op = -1;
 34     buf.sem_flg = SEM_UNDO;
 35 
 36     if( semop(semid,&buf,1) == -1)
 37     {
 38         printf("semop p err\n");
 39     }
 40 
 41 }
  42 void sem_v()
 43 {
 44     struct sembuf buf;
 45     buf.sem_num = 0;
 46     buf.sem_op = 1;
 47     buf.sem_flg = SEM_UNDO;
 48 
 49     if( semop(semid,&buf,1) == -1)
 50     {
 51         printf("semop p err\n");
 52     }
 53 }
 54 void sem_destory()
 55 {
 56     if(semctl(semid,0,IPC_RMID) == -1)
 57     {
 58         printf("semcti err destory\n");
 59     }
 60 
 61 }
 62 

            

sem.h

  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 #include<unistd.h>
  4 #include<string.h>
  5 #include<assert.h>
  6 #include<sys/sem.h>
  7 
  8 
  9 union semun
 10 {
 11     int  val;
 12 };
 13 
 14 void sem_init();
 15 void sem_p();
 16 void sem_v();
 17 void sem_destory();

编译链接
gcc -o a a.c sem.c
gcc -o b b.c sem.c

在这里插入图片描述

二 、 使三个进程进行有序的输出

A进程输出A ,B进程输出B ,C进程输出C
请设置信号量,使得输出结果为:
ABCABCABCABCABC

思考:
三个进程设置三个信号量,如图:
在这里插入图片描述

直接编写:
a.c

#include"sem.h"

int main()
{
    int res = sem_init();
    if(res == -1)
    {
        return 0;
    }

    for(int i = 0;i<5;i++)
    {
        sem_p(SEM1);
        printf("A");
        fflush(stdout);
        sleep(1);
        sem_v(SEM2);
    }
}

b.c

#include"sem.h"

int main()
{
    int res = sem_init();
    if(res == -1)
    {
        return 0;
    }

    for(int i = 0;i<5;i++)
    {
        sem_p(SEM2);
        printf("B");
        fflush(stdout);
        sleep(1);
        sem_v(SEM3);
    }
}

c.c

#include"sem.h"

int main()
{
    int res = sem_init();
    if(res == -1)
    {
        return 0;
    }

    for(int i = 0;i<5;i++)
    {
        sem_p(SEM3);
        printf("C");
        fflush(stdout);
        sleep(1);
        sem_v(SEM1);
    }
    sem_destory();
}

sem.h

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<sys/sem.h>

#define SEM_NUM   3
#define SEM1    0
#define SEM2   1 
#define SEM3   2


union semun 
{
    int val;
};

int sem_init();
void sem_p(int index);
void sem_v(int index);
void  sem_destory();


sem.c

#include"sem.h"
static int semid = -1;

int sem_init()
{
    semid = semget((key_t)1234,SEM_NUM,IPC_CREAT|IPC_EXCL|0600);
    if(semid == -1)
    {
        semid = semget((key_t)1234,SEM_NUM,0600);
        if(semid == -1)
        {
            printf("semget err\n");
            return -1;
        }
    }
    else 
    {
        int arr[SEM_NUM] = {1,0,0};
        for(int i = 0;i<SEM_NUM ;i++)
        {
            union semun a;
            a.val = arr[i];
            if(semctl (semid,i,SETVAL,a)== -1)
            {
                printf("semcti setval err\n");
                return -1;
            }
        }
    }
}
void  sem_p(int index)
{
   if(index <0 || index >= SEM_NUM)
   {
       return ;
   }

   struct sembuf buf;
   buf.sem_num = index ;
   buf.sem_op = -1;//p
   buf.sem_flg = SEM_UNDO;

   if( semop(semid,&buf,1) == -1)
   {
       return ;
   }
}
void sem_v(int index)
{
   if(index <0 || index >= SEM_NUM)
   {
      return ;
   }
 
   struct sembuf buf;
   buf.sem_num = index ;
   buf.sem_op =1;//v
   buf.sem_flg = SEM_UNDO;
 
   if(semop(semid,&buf,1) == -1)
   {
        return ;
   }
}


void sem_destory()
{
    if(semctl(semid,0,IPC_RMID) == -1)
    {
        return ;
    }
}


gcc -o a a.c sem.c
gcc -o b b.c sem.c
gcc -o c c.c sem.c

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值