栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

信号量,共享内存

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

信号量,共享内存

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

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

p:获取资源

v:释放资源

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

a程序
#include
#include
#include
#include
#include
#include信号量头文件


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 errn"); 
          return;
          }
     }else
     {
         全新创建成功,现在初始化
         union semun a;
         a.val=1;
         if(semctl(semid,0,SETVAL,a)==-1)失败
         {
            0表示对第几个信号量初始化,SETVAL将a的值赋给信号量
            printf("semctl errn");
         }
     }
}

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 errn");
    }
}


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 errn");
    }
}

void sem_destory()
{
    if(semctl(semid,0,IPC_RMID)==-1)删除信号量
    {  
        printf("semctl err destoryn");
    } 
}
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
#include
#include
#include
#include

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
#include
#include
#include

#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)
  {
      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
#include
#include
#include
#include
#include
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:%sn",s); 
     sem_v(SEM1);
    }
    shmdt(s);断开映射
    shmctl(shmid,IPC_RMID,NULL);删除共享内存
    sem_destroy();
}



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

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

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/589363.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号