perl信号量实现进程间通信

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
云数据库 RDS MySQL Serverless,价值2615元额度,1个月
简介: 开篇   近期在给一个客户编写数据库迁移工具,语言使用的是不太熟悉的perl。而需要做进程间通信源自这样一个需求,即并行迁移,想要真正的提升性能,我没有选择多线程的方式,而是直接选择多进程。   而我们都知道,多进程和多线程的区别就在于多进程的稳定性,多进程的内存资源是独立的,而多线程确实和父进程共享的。

开篇

  近期在给一个客户编写数据库迁移工具,语言使用的是不太熟悉的perl。而需要做进程间通信源自这样一个需求,即并行迁移,想要真正的提升性能,我没有选择多线程的方式,而是直接选择多进程。
  而我们都知道,多进程和多线程的区别就在于多进程的稳定性,多进程的内存资源是独立的,而多线程确实和父进程共享的。场景图示如下,
today1
  描述一下,首先通过简单的算法,将表大致平均地分到多个子进程,每个子进程任务完成后统计成功的表数量。那么统计表数量的变量就是关键了,在这里多个进程是需要共享这个变量的

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

使用

如下代码示例,

#!/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命令查看信号量集。
today3
  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]#

然后查看信号量,发现已经被销毁了
today4
那么现在再执行,信号量就应该是重新创建了,

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

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

结语

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

相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
5月前
|
消息中间件 存储 Linux
Linux进程间通信【消息队列、信号量】
Linux进程间通信【消息队列、信号量】
69 0
|
2天前
|
存储 安全 Linux
【Linux】详解进程通信中信号量的本质&&同步和互斥的概念&&临界资源和临界区的概念
【Linux】详解进程通信中信号量的本质&&同步和互斥的概念&&临界资源和临界区的概念
|
2月前
|
存储 Linux 程序员
Linux进程间通信(IPC)教程 Linux信号量:讲解POSIX信号量在Linux系统进程间通信中的编程实践
Linux进程间通信(IPC)教程 Linux信号量:讲解POSIX信号量在Linux系统进程间通信中的编程实践
21 1
|
7月前
|
Linux 程序员 数据安全/隐私保护
嵌入式 Linux进程间通信之信号量
嵌入式 Linux进程间通信之信号量
|
7月前
|
数据安全/隐私保护
计算机操作系统中实现进程间同步的信号量概念讲解
计算机操作系统中实现进程间同步的信号量概念讲解
49 0
|
9月前
|
消息中间件 缓存 算法
【Linux】进程间通信——system V共享内存 | 消息队列 | 信号量
system V共享内存、system V消息队列和system V信号量的介绍。
|
11月前
|
消息中间件 安全 Linux
Linux之进程间通信——system V(共享内存、消息队列、信号量等)(下)
Linux之进程间通信——system V(共享内存、消息队列、信号量等)(下)
86 0
|
11月前
|
消息中间件 存储 Linux
Linux之进程间通信——system V(共享内存、消息队列、信号量等)(上)
Linux之进程间通信——system V(共享内存、消息队列、信号量等)(上)
90 0
|
11月前
|
消息中间件 算法 Unix
进程间通信—管道,共享内存,消息队列,信号量
本文讲述了几种进程间通信的方式,包括具有亲缘关系进程使用的匿名管道,命名管道。systemV中共享内存,消息队列,还浅浅介绍了信号量概念,还有IPC资源之间的关系
11549 0
进程间通信—管道,共享内存,消息队列,信号量
|
12月前
|
消息中间件 存储 Linux
【Linux】进程间通信 --- 管道 共享内存 消息队列 信号量-1
【Linux】进程间通信 --- 管道 共享内存 消息队列 信号量-1