信号量,共享内存

临界区:访问临界资源的代码

临界资源:同一时刻只允许一个进程访问的资源

p:获取资源

v:释放资源

前台只能执行一个进程,后台可以执行多个所以a和b程序必须得放在后台,结果还是在前台显示

a程序
#include<stdlib.h>
#include<stdio.h>
#include<assert.h>
#include<unistd.h>
#include<string.h>
#include<sys/sem.h>信号量头文件


static int semid=-1;
union semun
{
  int val;
};

void sem_init()创建
{
     semid=semget((key_t)1234,1,IPC_CREAT|IPC_EXCL|0600);
     两个进程同一个key_t,代表一个信号量,1代表1个信号量
     创建|确保第一个创建(创建的得初始化)| 访问权限
     if(semid==-1)失败,说明已有人创建
     {
         semid=semget((key_t)1234,1,0600);获取
          if(semid==-1)
          {  printf("semid err\n"); 
          return;
          }
     }else
     {
         全新创建成功,现在初始化
         union semun a;
         a.val=1;
         if(semctl(semid,0,SETVAL,a)==-1)失败
         {
            0表示对第几个信号量初始化,SETVAL将a的值赋给信号量
            printf("semctl err\n");
         }
     }
}

void sem_p()
{
    struct sembuf buf;
    buf.sem_num=0;对第0个信号量进行操作
    buf.sem_op()=-1;值减1
    buf.sem_flg=SEM_UNDO;当程序不小心结束后,帮忙释放信号量
    if(semop(semid,&buf,1)==-1)1组信号量
    {
        printf("semop p err\n");
    }
}


void sem_v()
{
    struct sembuf buf;
    buf.sem_num=0;对第0个信号量进行操作
    buf.sem_op()=1;值加1
    buf.sem_flg=SEM_UNDO;当程序不小心结束后,帮忙释放信号量
    if(semop(semid,&buf,1)==-1)1个结构体变量
    {
        printf("semop v err\n");
    }
}

void sem_destory()
{
    if(semctl(semid,0,IPC_RMID)==-1)删除信号量
    {  
        printf("semctl err destory\n");
    } 
}
int main()
{
   sem_init();
   for(int i=0;i<5;++i)
   {
   sem_p();p操作
    printf("A");
    fflush(stdout);
    int n=rand()%3;
    sleep(n);
    printf("A");
    fflush(stdout);
    sem_v();v操作
    n=rand()%3;
    sleep(n);
    }
    sleep(10);
sem_destory();
}


b程序

#include<stdlib.h>
#include<stdio.h>
#include<assert.h>
#include<unistd.h>
#include<string.h>

int main()
{
for(int i=0;i>5;++i)
{
    sem_init();
    sem_p();
    printf("A");
    fflush(stdout);
    int n=rand()%3;
    sleep(n);
    printf("A");
    fflush(stdout);
    sem_v();
    n=rand()%3;
    sleep(n);
 }


}


结果为AABBAABBAABB或BBAABBAABBAA

让三个进程打印ABCABCABC,得设置三个信号量,s1(0),s2(1),s3(1)

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

#define SEM_NUM 3共设置三个信号量
#define SEM1 0三个信号量名
#define SEN2 1
#define SEN3 2

static int semid=-1;
union semun
{
  int val;
}

void sem_init()
{
  semid=semget((key_t)1234,SEN_NUM,IPC_CREAT|IPC_EXCL|0600);
  if(semid==-1)
  {
    semid=semget((key_t)1234,SEM_NUM,0600);
  }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("semctl 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;
  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;
  buf.sem_flg=SEM_UNDO;
  if(semop(semid,&buf,1)==-1)
  {
     return ;
  }
}


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



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);
     sem_v(SEM2);
  }
}


int main()
{
  int res=sem_init();
  if(res==-1)
  {
    return 0;
  }
  for(int i=0;i<5;++i)
  {
    sem_p(SEM1);
     printf("B");
     fflush(stdout);
     sem_v(SEM2);
  }
}


int main()
{
  int res=sem_init();
  if(res==-1)
  {
    return 0;
  }
  for(int i=0;i<5;++i)
  {
    sem_p(SEM2);
     printf("C");
     fflush(stdout);
     sem_v(SEM0);
  }
 sem_destory();
}

ipcs:可以查看共享内存,消息队列,信号量

共享内存

共享内存:内存中有一块既可以被A进程使用,B也可以使用

1.创建共享内存
2.将共享内存映射到进程中
3.断开映射
4.删除映射

ipcs -m只看共享内存

ipcs -q只看消息队列

ipcs -s只看信号量

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<assert.h>
#include<sys/shm.h>
a程序写
int main()
{
    int shmid=shmget((key_t)1234,128,IPC_CREAT|0600);
    128共享内存的大小
    assert(shmid!=-1);
    char* s=(char*)shmat(shmid.NULL,0);NULL代表由操统自行分配空间,0默认读写都可
    while(1)
    {
      printf("input:\n");
      char buff[128]={0};
      fgets(buff,128,stdin);
      sem_p(SEM0);
      strcpy(s,buff);像共享内存中写入hello
      sem_v(SEM1);
       if(strncmp(buff,"end",3)==0)
       {
         break;
       }
     }
    shmdt(s);断开映射
}

b程序读
int main()
{
    int shmid=shmget((key_t)1234,128,IPC_CREAT|0600);
    128共享内存的大小
    assert(shmid!=-1);
    char* s=(char*)shmat(shmid,NULL,0);NULL代表由操统自行分配空间,0默认读写都可
    while(1)
    {
    sem_p(SEM2);
      if(strncmp(s,"end",3)==0)
      {
        break;
      }
     printf("read:%s\n",s); 
     sem_v(SEM1);
    }
    shmdt(s);断开映射
    shmctl(shmid,IPC_RMID,NULL);删除共享内存
    sem_destroy();
}



ipcrm -s +标识符:删除信号量

ipcrm -m +标识符:删除共享内存

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值