perl信号量实现进程间通信

开篇

  近期在给一个客户编写数据库迁移工具,语言使用的是不太熟悉的perl。而需要做进程间通信源自这样一个需求,即并行迁移,想要真正的提升性能,我没有选择多线程的方式,而是直接选择多进程。
  而我们都知道,多进程和多线程的区别就在于多进程的稳定性,多进程的内存资源是独立的,而多线程确实和父进程共享的。场景图示如下,

  描述一下,首先通过简单的算法,将表大致平均地分到多个子进程,每个子进程任务完成后统计成功的表数量。那么统计表数量的变量就是关键了,在这里多个进程是需要共享这个变量的

  linux下的进程间通信,共有三个媒介,消息队列、共享内存段以及信号量。通常共享内存段和信号量配合使用,而这里我们只需要做简单的 持锁+计数+释锁,这么说来,此场景下信号量就是个天然的计数器了。
  这三种媒介可以使用ipcs命令查看,

使用

如下代码示例,

#!/usr/bin/perl
use IPC::SysV qw(S_IRWXU IPC_CREAT);
use IPC::Semaphore;

my $sem0;
my $sem1;
my @childs;

my $sem = IPC::Semaphore->new(1556, 1, S_IRWXU|IPC_CREAT)
        || die "IPC::Semaphore->new: $!\n";
##创建一个信号量集,1556是key,1是信号量的个数,S_IRWXU即700权限,IPC_CREAT没有则创建
$sem->setval(0,0);
##设置初始值,这里只有一个信号量则下标为0,初始值为0
for ($i=0; $i<5; $i++){
                if($pid=fork())
                        {
                        $childs[$i] = $pid;
                }elsif(defined $pid){
                        sleep(1);
                        $sem->op(0, +1, SEM_UNDO);
##op方法通过semop来调用系统PV原子操作,子进程退出时会通过 SEM_UNDO 来解锁
                        exit;
                }else{
                        print "Error!\n";
                        exit;
                }
}
        for  $p (@childs){
                waitpid($p, 0);
        }

$sem1 = $sem->getval(0);
##获取信号量值
print $sem1."\n";

其中涉及到的几个常用方法如下,

new ( KEY , NSEMS , FLAGS )
Create a new semaphore set associated with KEY . NSEMS is the number of semaphores in the set. A new set is created if
● KEY is equal to IPC_PRIVATE
● KEY does not already have a semaphore identifier associated with it, and FLAGS & IPC_CREAT is true.
On creation of a new semaphore set FLAGS is used to set the permissions. Be careful not to set any flags that the Sys V IPC implementation does not allow: in some systems setting execute bits makes the operations fail.

setval ( N , VALUE )
Set the N th value in the semaphore set to VALUE

op ( OPLIST )
OPLIST is a list of operations to pass to semop. OPLIST is a concatenation of smaller lists, each which has three values. The first is the semaphore number, the second is the operation and the last is a flags value.

getval ( SEM )
Returns the current value of the semaphore SEM .

输出结果如下

[root@mysqltest2 testconfig]# perl sem.pl
5
[root@mysqltest2 testconfig]#

销毁

执行完成之后,再使用ipcs命令查看信号量集。

  614转换成十进制数,即2566+161+4=1556,并且权限是700,这个信号量是不是很熟悉呢?

由于使用了IPC_CREAT这个flag,因此我们注释掉初始化操作,再执行一下程序看看。如下

my $sem = IPC::Semaphore->new(1556, 1, S_IRWXU|IPC_CREAT)
        || die "IPC::Semaphore->new: $!\n";
#$sem->setval(0,0);

执行结果如下,

[root@mysqltest2 testconfig]# perl sem.pl
10
[root@mysqltest2 testconfig]#

  从输出结果我们看到,由于信号量一直存在因此没有重新创建,PV操作也是基于上一次的结果继续进行的。

再次执行,

[root@mysqltest2 testconfig]# perl sem.pl
15
[root@mysqltest2 testconfig]#

remove方法。官方解释如下,

remove
  Remove and destroy the semaphore set from the system.

那么意义很明显,就是用来销毁信号量的。我们在代码尾部添加销毁语句,

$sem->remove();

再次执行结果如下,

[root@mysqltest2 testconfig]# perl sem.pl
20
[root@mysqltest2 testconfig]#

然后查看信号量,发现已经被销毁了

那么现在再执行,信号量就应该是重新创建了,

[root@mysqltest2 testconfig]# perl sem.pl
5
[root@mysqltest2 testconfig]#

  执行结果完全符合。最后两次的执行首先基于旧的信号量做操作,因此执行完毕时信号量值为20,然后销毁掉信号量,下次执行重新创建,因此最后一次的值为5。

结语

  只是几句简单的代码,却帮了我的大忙,理解至上。

时间: 2024-10-03 22:18:17

perl信号量实现进程间通信的相关文章

详解Linux多线程使用信号量同步_Linux

信号量.同步这些名词在进程间通信时就已经说过,在这里它们的意思是相同的,只不过是同步的对象不同而已.但是下面介绍的信号量的接口是用于线程的信号量,注意不要跟用于进程间通信的信号量混淆. 一.什么是信号量 线程的信号量与进程间通信中使用的信号量的概念是一样,它是一种特殊的变量,它可以被增加或减少,但对其的关键访问被保证是原子操作.如果一个程序中有多个线程试图改变一个信号量的值,系统将保证所有的操作都将依次进行. 而只有0和1两种取值的信号量叫做二进制信号量,在这里将重点介绍.而信号量一般常用于保护

Linux进程间通信学习:如何使用信号量

这篇文章将讲述别一种进程间通信的机制--信号量.注意请不要把它与之前所说的信号混淆起来,信号与信号量是不同的两种事物.有关信号的更多内容,可以阅读我的另一篇文章:Linux进程间通信--使用信号.下面就进入信号量的讲解. 一.什么是信号量 为了防止出现因多个程序同时访问一个共享资源而引发的一系列问题,我们需要一种方法,它可以通过生成并使用令牌来授权,在任一时刻只能有一个执行线程访问代码的临界区域.临界区域是指执行数据更新的代码需要独占式地执行.而信号量就可以提供这样的一种访问机制,让一个临界区同

Linux进程间通信(六) 信号量通信之semget()

信号量通信之semget().semctl().semop()及其基础实验 这个信号量理解起来是有点不容易啊,我看书看了好几遍才知道怎么回事.在讲这一节信号量之前,我还 是想先说几个小知识点,这也是我在学习完后最终理解的"精华",哈哈! 信号量是干啥的? 信号量就是用来解决进程间的同步与互斥问题的一种进程间通信机制. 同步与互斥的通俗理解 这两个名词咱们从字面上就能理解.举个例子吧,在创建子进程时,你是怎么保证父子进程执行的先后顺序呢 ?我在以前的时候是通过sleep()函数来实现的,

进程间通信之-信号量semaphore--linux内核剖析(十)

信号量 什么是信号量 信号量的使用主要是用来保护共享资源,使得资源在一个时刻只有一个进程(线程)所拥有. 信号量的值为正的时候,说明它空闲.所测试的线程可以锁定而使用它.若为0,说明它被占用,测试的线程要进入睡眠队列中,等待被唤醒. 为了防止出现因多个程序同时访问一个共享资源而引发的一系列问题,我们需要一种方法,它可以通过生成并使用令牌来授权,在任一时刻只能有一个执行线程访问代码的临界区域. 临界区域是指执行数据更新的代码需要独占式地执行.而信号量就可以提供这样的一种访问机制,让一个临界区同一时

Perl多进程与信号量

一.Perl多进程 今天这里就不多说什么是多进程.什么是多线程了,简单来说目的都是充分利用硬件资源,最大化机器性能. 任何语言的新手在遇到多进程编程时,心里往往会发怵,多进程好像很高大上.好复杂的样子,其实不然.我们要区分多进程实现本身和多进程应用编程,多进程本身的实现确实是很复杂的,但是我们更多的是集中在多进程应用编程,这部分就比较简单了. 话不多说,下面先看用perl实现的一个多进程编程例子. #!/bin/perl use strict; # fork returns the child

Linux进程间通信——使用信号量

这篇文章将讲述别一种进程间通信的机制--信号量.注意请不要把它与之前所说的信号混淆起来,信号与信号量是不同的两种事物.有关信号的更多内容,可以阅读我的另一篇文章:Linux进程间通信--使用信号.下面就进入信号量的讲解.   一.什么是信号量 为了防止出现因多个程序同时访问一个共享资源而引发的一系列问题,我们需要一种方法,它可以通过生成并使用令牌来授权,在任一时刻只能有一个执行线程访问代码的临界区域.临界区域是指执行数据更新的代码需要独占式地执行.而信号量就可以提供这样的一种访问机制,让一个临界

linux网络编程之进程间通信基础(二) 死锁、信号量与PV原语简介

一.死锁 (1) 死锁是指多个进程之间相互等待对方的资源,而在得到对方资源之前又不释放自己的资源,这样 ,造成循环等待的一种现象.如果所有进程都在等待一个不可能发生的事,则进程就死锁了. (2)死锁产生的必要 条件: 互斥条件 进程对资源进行排它性使用,即在一段时间内某资源仅为一个进程所占用. 请求和保持条件 当进程因请求资源而阻塞时,对已获得的资源保持不放. 不可剥夺条件 进程已获得的资源在未使用完之前,不能被剥夺,只能在使用完时由自己释放. 环路等待条件 各个进程组成封闭的环形链,每个进程都

UNIX环境高级编程:system V信号量

1. 信号量(semaphore)主要用于保护临界资源. 进程可以根据它判断是否能访问某些共享资源. 信号量除了用于访问控制外,还可用于进程同步,也就是进程间通信. 2. 信号量分类: a. 二值信号量: 信号量的值只能取0或1,类似于互斥锁mutex,但两者又不同: mutex 与 二值信号量的区别: 信号量强调共享资源,只要共享资源可用,其他进程同样可以修改信号量的值: 互斥锁更强调进程,占用资源的进程使用完资源后,必须由进程本身来接锁. b. 计数信号量:信号量的值可以取任意非负值. sy

Linux进程间通信学习:如何使用消息队列

下面来说说如何用不用消息队列来进行进程间的通信,消息队列与命名管道有很多相似之处.有关命名管道的更多内容可以参阅我的另一篇文章:Linux进程间通信--使用命名管道 一.什么是消息队列 消息队列提供了一种从一个进程向另一个进程发送一个数据块的方法.  每个数据块都被认为含有一个类型,接收进程可以独立地接收含有不同类型的数据结构.我们可以通过发送消息来避免命名管道的同步和阻塞问题.但是消息队列与命名管道一样,每个数据块都有一个最大长度的限制. Linux用宏MSGMAX和MSGMNB来限制一条消息