在操作系统中,使用信号量可以解决进程间的,信号量是进程通信方式

  在操作系统中,使用信号量可以解决进程间的,信号量是进程通信方式

  进程间通信——信号量信号量类似于道路上的红绿灯,在各个路口控制人们各个方向的前进,以便更好地有计划地使用这条道路。在程序中,信号控制进程的执行。什么是信号量问题:在一个程序中,有时有一段特殊的代码,同一时间只允许一个进程执行这部分代码。这个区域被称为“关键区域”。那么,在多进程并发执行中,当一个进程进入临界区时,由于某种原因被挂起,其他进程也可能进入该区。解决方法:3354使用信号量。什么是信号量?信号量是一个特殊的变量。我们只能对信号量执行P和V操作。p:申请资源。如果信号量值为0,则信号量为-1。如果信号量值=0,则进程被挂起。操作:释放资源。如果一个进程由于信号量而被挂起,当前进程将被恢复。如果没有进程因信号量而挂起,则将信号量设置为1。注意:P操作和V操作是原子操作,即在执行过程中不会被中断。这里的信号量是指System V IPC的信号量,与线程使用的信号量不同。这个信号量用于进程间通信。使用信号量的Semget函数原型:intsemget (key _ tkey,intnsems,intsemflg);函数:获取一个现有的信号量或创建一个新的信号量,并返回信号量的标识符。参数:key:键值,对应一个唯一的信号量。键值类似于共享内存。不同的可以通过这个键值和semget获得唯一的信号量。特殊键值——IPC_PRIVAT,只能由创建者进程访问,可用于父进程与子进程之间的通信。Nsems:所需信号量的数量,通常为1。Semflag:访问权限。如果设置了IPC_CREAT,如果信号量不存在,将创建信号量,如果信号量已经存在,则不会出现错误。返回值:成功:返回正整数。失败:返回-1。信号量运算的Semop函数原型:intsemop (intsemid,structsembuf * sops,unsigned ns ops);功能:改变信号量的值,即对信号量进行P运算和V运算。参数:semid:信号量标识符,即semget函数的返回值。Sops:是一个数组,元素类型是struct sembuf。struct sembuf { short sem _ num//信号量组中的编号(即指定操作哪个信号量)//semget实际上是获取一组信号量//信号量组中的编号从0开始短sem _ op//操作类型:-1表示P操作;1 v操作短路sem _ flg//通常是SEM_UNDO,让操作系统跟踪信号,//并在进程终止时释放信号量而不释放信号量}

  Nsops:表示第二个参数sops表示的数组大小,也就是有几个struct sembuf。返回值:成功:返回0。失败:返回-1。参考与补充:Linux进程间通信(5): semget()、semop()、semctl()信号量控制semctl函数原型:intsemctl (intsemid,intsem _ num,intcmd,);功能:控制信号量。参数:semid:信号量标识符。Sem_num:信号量组中的编号。如果只有一个信号量,取0。Cmd:通常是以下两个值之一。SETVAL:用于将信号量初始化为一个已知值。p的值由union semun中的val成员设置,该成员用于在第一次使用信号量之前设置信号量。IPC_RMID:用于删除不再需要的信号量标识符。这四个参数类型是:union semun。工会联合会

  int val//要由setval命令设置的值

  struct semid _ ds * buf

  无符号短*数组;

  }

  Union semun有些Linux发行版是在sys/sem.h中定义的,有些则是未定义的。可以自己定义:#if defined(__GNU_LIBRARY__)!defined(_ SEM _ SEMUN _ UNDEFINED)# else

  工会联合会

  int val

  struct semid _ ds * buf

  无符号短整型*数组;

  struct seminfo * _ _ buf

  #endif

  返回值:省略,详见-semctl (2)-Linux手册页。相关参考及补充:Linux进程间通信(5):信号量semget()、semop()、semctl()示例例1:不使用信号量同时执行多个程序,观察对临界段的访问。#包含stdlib.h

  #包含stdio.h

  int main(void) {

  int I;

  PID _ t PD=fork();

  for(I=0;i i ) {

  /*模拟关键区域-开始*/

  printf(Process(%d) In\n ,getpid());

  睡眠(1);

  printf(Process(%d) Out\n ,getpid());

  /*模拟临界区-结束*/

  睡眠(1);

  }

  返回0;

  }

  可见不是我们想要的效果。我们要的是一个能进,一个不能进,一个能出,一个能进。

  例2:使用信号量,并发指定多个进程,观察对临界区的访问。#包含sys/types.h

  #包含sys/ipc.h

  #包含系统/sem.h

  #包含stdlib.h

  #包含stdio.h

  #如果定义了(__GNU_LIBRARY__)!已定义(_SEM_SEMUN_UNDEFINED)

  #否则

  工会联合会

  int val

  struct semid _ ds * buf

  无符号短整型*数组;

  struct seminfo * _ _ buf

  };

  #endif

  //信号的初始化

  静态SEM _ initial(int semi){

  int ret

  联盟semun semun

  semun . val=1;

  ret=SEM CTL(semi,0,SETVAL,semun);

  if(ret==-1){

  fprintf(stderr, semctl失败!\ n’);

  }

  返回ret

  }

  //将p v操作封装到一个函数中

  //p操作

  静态int SEM _ p(int semi){

  int ret

  结构sembuf sembuf

  sembuf . SEM _ op=-1;//运算类型,设置为-1,即P运算。

  SEM buf . SEM _ num=0;//指定信号量组中信号量的数量。

  SEM buf . SEM _ flg=SEM _ UNDO;//让操作系统跟踪信号,如果进程忘记释放,操作系统会负责释放。

  ret=semop(semi,sembuf,1);//根据设置操作信号量

  if (ret==-1) {

  fprintf(stderr, sem_p失败!\ n’);

  }

  返回ret

  }

  //v操作

  静态int SEM _ v(int semi){

  int ret

  结构sembuf sembuf

  SEM buf . SEM _ op=1;//运算类型,设置为1,即V运算。

  SEM buf . SEM _ num=0;//指定信号量组中信号量的数量。

  SEM buf . SEM _ flg=SEM _ UNDO;//让操作系统跟踪信号,如果进程忘记释放,操作系统会负责释放。

  ret=semop(semi,sembuf,1);//根据设置操作信号量

  if (ret==-1) {

  fprintf(stderr, sem_v失败!\ n’);

  }

  返回ret

  }

  int main(int argc,char* argv[]) {

  int semid

  //获得信号

  semi=SEM get((key _ t)1234,1,0666 IPC _ CREAT);

  if(semi==-1){

  printf(semget失败!\ n’);

  出口(1);

  }

  //信号量的初始化

  if (argc 1) {

  int ret=SEM _ initial(semi);

  if (ret==-1) {

  出口(1);

  }

  }

  for(;){

  if(SEM _ p(semi)==-1){//p operation,application,如果没有可用的资源,则暂停等待。

  出口(1);

  }

  /*模拟关键区域-开始*/

  printf(Process(%d) In\n ,getpid());

  睡眠(3);

  printf(Process(%d) Out\n ,getpid());

  /*模拟临界区-结束*/

  if(SEM _ v(semi)==-1){//v运算,释放。

  出口(1);

  }

  }

  返回0;

  }

  你看,一个能出来,一个能进去。

  转载请联系作者取得转载授权,否则将追究法律责任。

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

相关文章阅读

  • office2010激活密钥大全 怎么永久激活office2010
  • project2010产品密钥免费_project2010激活密钥永久激活码
  • c语言调用退出函数 c语言退出整个程序怎么写
  • c语言中怎么给函数初始化 c语言的初始化语句
  • c语言编写函数计算平均值 c语言求平均函数
  • chatgpt是什么?为什么这么火?
  • ChatGPT为什么注册不了?OpenAI ChatGPT的账号哪里可以注册?
  • OpenAI ChatGPT怎么注册账号?ChatGPT账号注册教程
  • chatgpt什么意思,什么是ChatGPT ?
  • CAD中怎么复制图形标注尺寸不变,CAD中怎么复制图形线性不变
  • cad中怎么创建并使用脚本文件,cad怎么运行脚本
  • cad中快速计算器的功能,cad怎么快速计算
  • cad中快速修改单位的方法有哪些,cad中快速修改单位的方法是
  • cad中心点画椭圆怎么做,cad轴测图怎么画椭圆
  • CAD中常用的快捷键,cad各种快捷键的用法
  • 留言与评论(共有 条评论)
       
    验证码: