您好、欢迎来到现金彩票网!
当前位置:2019正版免费全年资料 > 同步通信量 >

多进程编程之进程间通信-共享内存信号量和套接字

发布时间:2019-06-12 04:07 来源:未知 编辑:admin

  为了防止出现因多个程序同时访问一个共享资源而引发的一系列问题,我们需要一种方法,它可以通过生成并使用令牌来授权,在任一时刻只能有一个执行线程访问代码的临界区域。临界区域是指执行数据更新的代码需要独占式地执行。而信号量就可以提供这样的一种访问机制,让一个临界区同一时间只有一个线程在访问它,也就是说信号量是用来调协进程对共享资源的访问的。

  信号量是一个特殊的变量,程序对其访问都是原子操作,且只允许对它进行等待(即P(信号变量))和发送(即V(信号变量))信息操作。最简单的信号量是只能取0和1的变量,这也是信号量最常见的一种形式,叫做二进制信号量。而可以取多个正整数的信号量被称为通用信号量。这里主要讨论二进制信号量。

  由于信号量只能进行两种操作等待和发送信号,即P(sv)和V(sv),他们的行为是这样的,假设有一个信号量变量sv:

  P(sv):如果sv的值大于零,就给它减1;如果它的值为0,就挂起该进程的执行。

  V(sv):如果有其他进程因等待sv而被挂起,就让它恢复运行,如果没有进程因等待sv而挂起,就给它加1。

  举个例子,就是两个进程共享信号量sv,一旦其中一个进程执行了P(sv)操作,它将得到信号量,并可以进入临界区,使sv减1。而第二个进程将被阻止进入临界区,因为当它试图执行P(sv)时,sv为0,它会被挂起以等待第一个进程离开临界区域并执行V(sv)释放信号量,这时第二个进程就可以恢复执行。

  第一个参数key是整数值(唯一非零),不相关的进程可以通过它访问一个信号量,它代表程序可能要使用的某个资源,程序对所有信号量的访问都是间接的,程序先通过调用semget函数并提供一个键,再由系统生成一个相应的信号标识符(semget函数的返回值),只有semget函数才直接使用信号量键,所有其他的信号量函数使用由semget函数返回的信号量标识符。如果多个程序使用相同的key值,key将负责协调工作。

  第三个参数sem_flags是一组标志,当想要当信号量不存在时创建一个新的信号量,可以和值IPC_CREAT做按位或操作。设置了IPC_CREAT标志后,即使给出的键是一个已有信号量的键,也不会产生错误。而IPC_CREAT IPC_EXCL则可以创建一个新的,唯一的信号量,如果信号量已存在,返回一个错误。

  第一个参数,sem_id是由semget返回的信号量标识符。第二个参数sem_ops是指向一个sembuf结构数组的指针,每个数组元素至少包含以下几个成员:

  前两个参数与前面一个函数中的一样,分别是信号量标识符和信号量编号。command表示将要采取的动作,通常是下面两个值中的其中一个:

  SETVAL:用来把信号量初始化为一个已知的值。p 这个值通过union semun中的val成员设置,其作用是在信号量第一次使用前对它进行设置。

  semctl函数将根据command参数的不同而返回不同的值,对于SETVAL和IPC_RMID如果成功时,返回0,失败时返回-1。

  将两个不同字符的输出来表示进入和离开临界区域,如果程序启动时带有一个参数,它将在进入和退出临界区域时候打印字符X;而程序的其他运行实例将在进入和退出临界区域的时候打印字符O,因为在任一给定时刻,只能有一个进程可以进入到临界区域,所以字符X和字符O应该是成对出现的。

  同时运行一个程序的两个实例,注意第一次运行时,要加上一个字符作为参数,例如本例中的字符 1,它用于区分是否为第一次调用。因为每个程序都在其进入临界区后和离开临界区前打印一个字符,所以每个字符都应该成对出现,正如你看到的上图的输出那样。在main函数中循环中我们可以看到,每次进程要访问stdout(标准输出),即要输出字符时,每次都要检查信号量是否可用(即stdout有没有正在被其他进程使用)。所以,当一个进程A在调用函数semaphore_p进入了临界区,输出字符后,调用sleep时,另一个进程B可能想访问stdout,但是信号量的P请求操作失败,只能挂起自己的执行,当进程A调用函数semaphore_v离开了临界区,进程B马上被恢复执行。然后进程A和进程B就这样一直循环了10次。

  另一个例子来说明一下,它实现的功能与前面的例子一样,运行方式也一样,都是两个相同的进程,同时向stdout中输出字符,只是没有使用信号量,两个进程在互相竞争stdout。它的代码如下:

  从上面的输出结果,我们可以看到字符‘X’和‘O’并不像前面的例子那样,总是成对出现,因为当第一个进程A输出了字符后,调用sleep休眠时,另一个进程B立即输出并休眠,而进程A醒来时,再继续执行输出,同样的进程B也是如此。所以输出的字符就是不成对的出现。这两个进程在竞争stdout这一共同的资源。

  信号量是一个特殊的变量,程序对其访问都是原子操作,且只允许对它进行等待(即P(信号变量))和发送(即V(信号变量))信息操作。我们通常通过信号来解决多个进程对同一资源的访问竞争的问题,使在任一时刻只能有一个执行线程访问代码的临界区域,也可以说它是协调进程间的对同一资源的访问权,也就是用于同步进程的。

  共享内存是最快的IPC(进程间通信)方式,它允许两个不相关进程访问同一个逻辑内存。共享内存是一个程序向内存写数据,另一个程序读数据,共享内存牵扯到同步的问题,一般有三种方案可以实现共享资源的同步。它们分别是信号量,记录锁和互斥量。

  使用信号量,首先服务端创建一个只含一个信号的信号量集合,并初始化为1。占据资源,则以sem_op=-1调用semop函数。释放资源,则则以sem_op=1调用semop函数。

  使用记录锁,需要创建一个文件,并写入一个字节。分配资源,对文件获得写锁,释放资源,解锁。

  使用互斥量,需要所有的进程将相同的文件映射到他们的地址空间,并使用PTHREAD_PROCESS_SHARED互斥量属性在文件中初始化互斥量。分配资源,对互斥量加锁,释放资源,解锁互斥量。

  用于开辟或指向一块共享内存,返回获得共享内存区域的ID(共享内存标识符),该标识符用于后续的共享内存函数。如果不存在指定的共享区域就创建相应的区域。 如果创建失败,则返回-1。

  keyt key: 共享内存的标识符。如果是父子关系的进程间通信的话,这个标识符用IPC_PRIVATE来代替。

  如果两个进程没有任何关系,所以就用ftok()算出来一个标识符(或者自己定义一个)使用了。

  int flag: 包含9个比特的权限标志,它是这块内存的模式(mode)以及权限标识。由IPC_CREAT定义的一个特殊比特必须和权限标志按位或才能创建一个新的共享内存段。设置IPC_CREAT标志的同时,给shmget函数传递一个已有共享内存段的键并不是一个错误,如果无需用到IPC_CREAT标志,该标志会被悄悄地忽略掉。

  权限标志的存在,使得允许一个进程创建的共享内存可以被共享内存的创建者所拥有的进程写入,同时其他用户创建的进程只能读取该共享内存。可以利用这个功能提高一种有效的对数据进行只读访问的方法,通过将数据放入共享内存并设置它的权限,即可避免数据被其他用户修改。

  将“模式” 和“权限标识”进行或运算,做为第三个参数。如:IPC_CREAT IPC_EXCL 0640

  其中0640为权限标识,4/2/1 分别表示读/写/执行3种权限,第一个0是UID,第一个6(4+2)表示拥有者的权限,第二个4表示同组权限,第3个0表示他人的权限。

  第一次创建共享内存时,它不能任何进程访问,要想启用对该共享内存的访问,必须将其连接到一个进程的地址空间中。

  char *shmaddr: 共享内存连接到进程中的起始地址,如果shmaddr为NULL,内核会把共享内存映射到系统选定的地址空间中;如果shmaddr不为NULL,内核会把共享内存映射到shmaddr指定的位置。

  注:一般情况下我们很少需要控制共享内存连接的地址,通常都是让系统来选择一个地址,否则就会使应用程序对硬件的依赖性过高。所以一般把shmaddr设为NULL。

  SHM_RDONLY是只读模式。需要注意的是,共享内存的读写权限由它的属主、它的访问权限和当前进程的属主共同决定。如果当shmflg & SM_RDONLY为true时,即使该共享内存的访问权限允许写操作,它也不能被写入。该参数通常会被设为0。

  shmdt()与shmat()相反,是用来禁止本进程访问一块共享内存的函数。

  IPC_STAT 得到共享内存的状态:把shmid_ds结构中的数据设置为共享内存的当前关联值

  IPC_SET 改变共享内存的状态:把共享内存的当前关联值设置为shmid_ds结构中给出的值

  简单了解共享内存: 实验目的与要求1、掌握Linux下共享内存的概念与使用方法;2、掌握环形缓冲的结构与使用方法;3、掌握Li...博文来自:xk_moving的博客

  更多技术文章地址:实验目的通过编写共享内存实验,进一步了解使用共享内存的具体步骤,同时加深对共享...博文来自:weixin_42800884的博客

  Linux/Unix系统IPC是各种进程间通信方式的统称,但是其中极少能在所有Linux/Unix系统实现中进行移植。随着POSIX和OpenGroup(X/Open)标准化的推进呵护影响的扩大,情况...博文来自:tf_apologize的博客

  共享内存是SystemV版本的最后一个进程间通信方式。共享内存,顾名思义就是允许两个不相关的进程访问同一个逻辑内存,共享内存是两个正在运行的进程之间共享和传递数据的一种非常有效的方式。不同进程之间共享...博文来自:ypt

  下面将讲解进程间通信的另一种方式,使用共享内存。一、什么是共享内存顾名思义,共享内存就是允许两个不相关的进程访问同一个逻辑内存。共享内存是在两个正在运行的进程之间共享和传递数据的一种非常有效的方式。不...博文来自:ljianhui的专栏

  前边说过,进程间通信的实质就是让两个不相干的进程看到同一份公共的资源,而内存是资源的一种,那么,如果让两个进程可以使用同一块内存,两个进程都可以往这块内存里边写东西和取东西,这不就是实现...博文来自:半暖的博客

  基本概念共享内存共享内存区是最快的IPC形式。一旦这样的内存映射到共享它的进程的地址空间,这些进程间数据传递不再涉及到内核,换句话说是进程不再通过执行进入内核的系统调用来传递彼此的数据。用管道...博文来自:lzjsqn的专栏

  前言共享内存可以说是最有用的进程间通信方式,也是最快的IPC形式。两个不同的进程A、B共享内存的基本原理是,同一块物理内存映射到进程A、B各自的进程地址空间。进程A可以即时看到B对共享内存中数据的更新...博文来自:私房菜之 --学--无--止--境--

  共享内存:1.共享内存就是允许两个不相关的进程访问同一个逻辑内存;          2.共享内存是在两个正在运行的进程之间共享和传递数据的一种最有效的方式;          3.不同进程之间共享的...博文来自:wangiijing的博客

  在程序的运行中,我们必定会有关于进程与进程间通信的问题。而我们的先辈早已为我们准备了关于解决这些问题的方法。这些方法主要有几种:无名管道,有名管道,信号,消息队列,共享内存以及信号灯(信号量)等几种方...博文来自:华清远见 程序员的学习天堂

  学习环境centos6.5Linux内核2.6什么是共享内存共享内存允许两个或更多进程访问同一块内存。当一个进程改变了这块内存中的内容的的时候,其他进程都会察觉到这个更改。效率:因为所有进程共享同一块...博文来自:春风来不来的博客

  今天我们来介绍Linux下最高效的一种进程间通信方式–共享内存。什么是共享内存?顾名思义,共享内存就是两个(或多个)进程共同占有一段内存空间,这些进程可以是有亲缘关系的进程,也可以是完全不相关的进程。...博文来自:上善若水,人淡如菊

  概念了解上一篇博客的socket程序只能实现服务器连接一个客户端,不能解决并发问题,及多个客户端同时连接。下面的程序采用多进程的思想,在accept()调用之后利用fork()产生子进程代码实现#in...博文来自:向念freetree

  众所周知,使用多进程的服务端模型有利于程序的健壮性。传统的做法是主进程负责收发数据,然后传给子进程来处理。这种做法的缺陷是需要大量的父子进程IPC,对效率来说是一种损失。这里,我提出另外一种比较独特的...博文来自:nokianasty的专栏

  共享内存和信号量实现进程间通信的另外两种机制。一. 共享内存1.共享内存的结构2.实现共享内存的函数(1)shmget函数功能:创建共享内存参数:key共享内存的名字,size共享内存的大小(以页为单...博文来自:的博客

  首先介绍一个概念IPCIPC(Inter-ProcessCommunication)机制即进程间通信机制,我们最为熟悉的IPC机制有三种,即信号量、共享内存和消息队列。今天要介绍的共享内存机制就是IP...博文来自:Zkr吖頭~的博客

  共享内存:是被多个进程共享的一部分物理内存.共享内存是进程间共享数据的一种最快的方法,一个进程向共享内存区域写入了数据,共享这个内存区域的所有进程就可以立刻看到其中的内容.创建共享内存,使用shmge...博文来自:无锡小徐的博客

  Linux信号量同步共享内存实验. Linux信号量同步共享内存实验. 简述 程序流程 信号量和共享内存的系统函数 信号量系统函数及接口 共享内存系统函数及接口 ...博文来自:艾露米婭娜

  一、简介共享内存为在多个进程之间共享和传递数据提供了一种有效的方式。但它本身并未提供同步机制。在实际编程中,可以使用 信号量, 传递消息(使用管道或IPC消息), 生成信号, 条件变量,等方法来提供读...博文来自:工作日志

  每一个进程都有着自己独立的地址空间,比如程序之前申请了一块内存,当调用fork函数之后,父进程和子进程所使用的是不同的内存。因此进程间的通信,不像线程间通信那么简单。但是共享内存编程接口可以让一个进程...博文来自:无名小鱼

  理论很多,我们需要的是代码实践,呵呵!来自:向共享内存中写入People*/#include#in...博文来自:Mr.Right的专栏

  最近一直在研究多进程间通过共享内存来实现通信的事情,以便高效率地实现对同一数据的访问。本文中对共享内存的实现采用了系统V的机制,我们的重点在于通过信号量来完成对不同进程间共享内存资源的一致性访问,共享...博文来自:zacklin的专栏

  多进程间通信常用的技术手段包括共享内存、消息队列、信号量等等,Linux系统下自带的ipcs命令是一个极好的工具,可以帮助我们查看当前系统下以上三项的使用情况,从而利于定位多进程通信中出现的通信问题。...博文来自:axiaochong的专栏

  进程可以直接读写内存,不需要任何数据的复制。为了在多个进程间交换信息,内核专门留出一块内存区,内存区可以由需要访问的进程将其映射到自己的私有地址空间,进程直接读写这一内存区,而不需要进行数据的复制,提...博文来自:manchestermi的博客

  一.信号量l信号量:解决进程之间的同步与互斥的IPC机制 多个进程同时...博文来自:chenyijun的专栏

  通信方法无法介于内核态与用户态的原因管道(不包括命名管道)局限于父子进程间的通信。消息队列在硬、软中断中无法无阻塞地接收数据。信号量无法介于内核态和用户态使用。内存共享需要信号量辅助,而信号量又无法使...博文来自:yangcs2009的专栏

  本文主要介绍下在多进程中使用信号量semaphore的方法。在上一文中,我们已经知道semaphore和mutex对临界区访问控制的一个最主要区别就是semaphore可以跨进程使用,而mutex只能...博文来自:Hyman的博客

  前言作为一个刚刚完成研究生阶段学习初入职场的小白菜,而且还是从机械电子工程专业转到软件工程师这样一个小的转行,在刚刚进行工作的3个月,犹如填鸭式的学习了很多之前写代码并不会用到的功能。在碰到的很多问题...博文来自:的博客

  如题,多个进程同时对共享内存部分进行读写操作,怎样使用加解锁方式实现进程间互斥访问共享内存,不能使用信号量互斥!请求高人指点!!!!论坛

  前面介绍了进程通信的几种方式,信号量,管道,消息队列,今天主要总结下共享内存的知识点。什么是共享内存我们一张图来解释什么叫共享内存。我们知道,每个进程都有一个叫PCB(Linux下一般为task_st...博文来自:xy913741894的博客

  一、共享内存概述在后台开发中,经常需要在多进程间进行数据共享,共享内存是一个较常见的选择。其他的IPC方式,包括磁盘文件、信号、套接字、管道、消息队列等,在需要传输大量数据时,性能都逊于共享内存。 共...博文来自:u011244446的专栏

  共享内存是所有IPC方式中最快的一种,原因在于共享内存一旦映射到进程地址空间,进程间数据的传递就不需要涉及内核。对于管道、FIFO和消息队列,两个进程之间通过这三种方式进行通信,则内核就扮演着“中转站...博文来自:L__xing的博客

  一、什么是共享内存?        共享内存(sharedmemory)是Unix下的多进程之间的通信方法,这种方法通常用于一个程序的多进程间通信,实际上多个程序间也可以通过共享内存来传递信息。共享内...博文来自:sinat_34866256的博客

  读写锁,就是多人可以同时访问,但是同时只有一个人可以修改的规则。由于锁本身的申请和释放,对于性能有很大的消耗,那么一般写只发生在特殊情况,也就是很少发生。读锁常在就是性能的优化方案,只有在申请写锁的时...博文来自:秦涧泉的博客

  共享内存区概述共享内存区是IPC形式中最快的,一旦这样的内存区映射到共享它的进程的地址空间,这些进程间的数据传递就不再涉及内核(进程不再通过执行任何进入内核的系统调用来彼此传递信息)。但是往该共享内存...博文来自:Hulk

  我在网上没找到这方面的程序,但是手头有道题: 内容:reader和writer两个进程通过共享内存交换数据。writer从标准输入读入字符串写入共享内存,reader把共享内存里的字符串打印到标准输出论坛

  共享内存(sharedmemory):是linux下的多进程之间的通信方法,这种方法通常用于一个程序的多进程间通信,实际上多个程序间也可以通过共享内存来传递信息。共享内存指在多处理器的计算机系统中,可...博文来自:xy的博客

  文章参考自:(ljianhui的专栏)以及博文来自:mick_seu的博客

  本篇文章是根据我的上篇博客,给出的改进版,由于时间有限,仅做了一个简单的优化。相关文章:将excel导入数据库2018年4月1日,新增下载地址链接:点击打开源码下载地址十分抱歉,这个链接地址没有在这篇...博文来自:Lynn_Blog

  最近比较有空,大四出来实习几个月了,作为实习狗的我,被叫去研究Docker了,汗汗! Docker的三大核心概念:镜像、容器、仓库 镜像:类似虚拟机的镜像、用俗话说就是安装文件。 容器:类似一个轻量...博文来自:我走小路的博客

  前言:前段时间做项目用到了图片裁剪,调用系统裁剪图片,结果在我的小米3上一直有问题,裁剪界面打不开,在其他设备上没问题,于是研究其他软件是怎么做的,淘宝的裁剪图片是自己做的,当然没问题,京东的是调用的...博文来自:zwenkai

  Intellij IDEA 如何通过数据库表生成带注解的实体类图文详细教程 Intellij IDEA 如何通过数据库表生成带注解的实体类 Contents 第一步:新建...博文来自:liu_yulong的专栏

  灰度图像的自动阈值分割(Otsu 法)机器视觉领域许多算法都要求先对图像进行二值化。这种二值化操作阈值的选取非常重要。阈值选取的不合适,可能得到的结果就毫无用处。今天就来讲讲一种自动计算阈值的方法。这...博文来自:Ivan 的专栏

  用以前以前写过的自定义课表软件 ,Android 自定义View课程表表格 原生View截图合成分享的图片 看到的是图片只显示到11节处,下面的没有...博文来自:ShallCheek

  本matplotlib安装过程在一定程度上参考了 因为学习机器学习的需要,又准备参考《机器学...博文来自:SCUT_Arucee的博客

  1.为什么是Fiddler? 抓包工具有很多,小到最常用的web调试工具firebug,达到通用的强大的抓包工具wireshark.为什么使用fiddler?原因如下: a.Firebug虽然可以抓包...博文来自:专注、专心

  servlet页面代码:@每次请求时产生一个token(一般为时间戳),存于session中并随之用hidden提交,在servlet中判断接收到的token和session中的是否一致来判断是否重复...博文来自:高调做事,低调做人!

  首先,确定你已经有了CSR证书请求、开发证书和App ID。如果你不是第一次开发iOS应用程序,那么你可能已经有了这些东西。那么你可以继续以下的步骤。一、配置App ID登录你的provisionin...博文来自:kmyhy的专栏

  目前还没有写出这个demo,不过可以参考下面这两个链接,一个是显示日期的,还有一个是合并单元格: 合并单元格: 博文来自:dddd的博客

  以回归为例吧,回归在某些场合可能更精准 支持连续变量和类别变量,类别变量就是某个属性有三个值,a,b,c,需要用Feature Transformers中的vectorindexer处理 上来是一堆...博文来自:chencheng12077的博客

  扫二维码关注,获取更多技术分享 本文承接之前发布的博客《 微信支付V3微信公众号支付PHP教程/thinkPHP5公众号支付》必须阅读上篇文章后才可以阅读这篇文章。由于最近一段时间工作比较忙,...博文来自:Marswill

  强连通分量: 简言之 就是找环(每条边只走一次,两两可达) 孤立的一个点也是一个连通分量   使用tarjan算法 在嵌套的多个环中优先得到最大环( 最小环就是每个孤立点)   定义: int Ti...博文来自:九野的博客

  jquery/js实现一个网页同时调用多个倒计时(最新的) 最近需要网页添加多个倒计时. 查阅网络,基本上都是千遍一律的不好用. 自己按需写了个.希望对大家有用. 有用请赞一个哦! //js ...博文来自:Websites

  简述关于gif的使用在实际项目中我用的并不多,因为我感觉瑕疵挺多的,很多时候锯齿比较严重,当然与图存在很大的关系。关于生成gif的方法可以提供一个网站preloaders,基本是可以满足需求的。简述 ...博文来自:本博客暂停更新,后期专注维护个人公众号『高效程序员』,欢迎关注!

  今天为了休息下,换换脑子,于是就找到了我之前收藏的一篇python的文章,是关于ddos攻击的一个脚本,正好今天有空,就实践下了。 附上源码pyDdos.py: #!/usr/bin/env ...博文来自:jeepxiaozi的专栏

http://disyu.com/tongbutongxinliang/307.html
锟斤拷锟斤拷锟斤拷QQ微锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷微锟斤拷
关于我们|联系我们|版权声明|网站地图|
Copyright © 2002-2019 现金彩票 版权所有