Perl多进程与信号量

Perl语言的并发编程 Perl 提供了多种方式来实现并发编程,包括线程、进程和事件驱动等。每种方式都有各自的优缺点,开发者可以根据具体需求选择合适的实现方式。理解并发编程的基本概念、特性和技巧,对于构建高效、响应迅速的 Perl 应用至关重要。在实际应用中,选择一种并发模型通常需要考虑到数据安全性、性能、系统架构等因素。希望本文能为 Perl 开发者在并发编程方面提供一定的指导。通过应用本文所讲的的知识,希望您的 Perl 项目能够高效、稳定地运行。 阅读详情

一、Perl多进程

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

#!/bin/perl
use strict;

# fork returns the child pid to parent, 0 to child or undef if failed to fork.
my $pid = fork();
die "fork failed" unless defined $pid;
if($pid > 0){
  my $i = 1000;
  while($i > 0){
    print "parent process i = $i\n";
    $i--;
  }
}elsif($pid == 0){
  my $i = 1000;
  while($i > 0){
    print "child process i = $i\n";
    $i--;
  }
}

上述例子中,实现多进程最关键的方法就是fork,其功能是将当前代码完全拷贝一份,也就是形成两份相同的程序:父进程和子进程。其中,在父进程中,fork的返回值是子进程的进程号(大于0的值);而在子进程中,fork返回值是0;fork失败时返回的值为负数。fork失败的情况一般是资源耗尽,我自己在编程时遇到过几次,都是fork太多的进程耗尽了系统资源。
通过以上三个返回值,我们就能确定fork有没有成功,以及成功时谁是父进程、谁是子进程,这样就可以决定在父进程或者子进程中做什么样的操作。
例子中父、子进程都是循环输出1000至1,同时给出父子进程提示信息。
输出结果如下:

parent process i = 36
child process i = 254
parent process i = 35
child process i = 253
parent process i = 34
child process i = 252
parent process i = 33
child process i = 251
parent process i = 32
child process i = 250
parent process i = 31
child process i = 249
parent process i = 30
child process i = 248
parent process i = 29
child process i = 247
parent process i = 28
child process i = 246
parent process i = 27
child process i = 245
parent process i = 26
child process i = 244
parent process i = 25
child process i = 243
parent process i = 24
child process i = 242
child process i = 241
child process i = 240
parent process i = 23
child process i = 239
parent process i = 22
child process i = 238
parent process i = 21
child process i = 237
parent process i = 20
child process i = 236
parent process i = 19
child process i = 235
parent process i = 18
child process i = 234
parent process i = 17
child process i = 233
parent process i = 16
child process i = 232

二、僵尸进程

1、什么是僵尸进程?

简单来讲(我最喜欢简单来讲),子进程完成使命(死了),却没有被父进程回收(收尸),什么作用都没有了,却还暂留在系统中,就像僵尸。进程变为僵尸进程时其所占用的资源都会被回收掉,因此不会造成太大的资源泄露,当然,进程本身的信息(进程号,创建时间等)还是存在的。

2、为什么会产生僵尸进程?如何回收?

一般情况是父进程比子进程提前结束并且没有任何其它进程来回收子进程时就会产生僵尸进程,例如我们在程序中没有指明父进程需要等待子进程全部结束并回收子进程时,子进程就会成为僵尸进程。
避免产生僵尸进程需要用到wait或者waitpid函数,这里我使用的是waitpid($pid,0)函数。该函数的功能是等待$pid进程结束并回收它。
代码如下:

#!/bin/perl
use strict;

# fork returns the child pid to parent, 0 to child or undef if failed to fork.
my $pid = fork();
die "fork failed" unless defined $pid;
if($pid > 0){
  my $i = 1000;
  while($i > 0){
    print "parent process i = $i\n";
    $i--;
  }
  # 等待子进程结束并回收它
  waitpid($pid,0);
}elsif($pid == 0){
  my $i = 1000;
  while($i > 0){
    print "child process i = $i\n";
    $i--;
  }
}

三、信号量(进程同步)

不需要多么仔细的观察就能发现第一个样例程序中,两个进程是并行执行的,这或许正是我们使用进程的目的。但是,有些时候,比如说两个进程都需要使用某个资源,而这个资源不能被两个进程同时使用,因此我们希望这两个进程串行执行。这个时候我们就需要使用锁这种东西来确保进程同步。
在这里,我使用了IPC的信号量,并让信号量资源值为1,当资源值为1时,其作用相当于锁。

# new一个信号量集(信号量数组,下标从0开始),第二个参数1表示该信号量集中只有一个信号量(下标为0),其它值为系统定义参数
our $sem = IPC::Semaphore->new(IPC_PRIVATE, 1, S_IRUSR | S_IWUSR | IPC_CREAT);
# 设定信号量集中下标为0的信号量资源值为1
$sem->setval(0,1);
# 该操作表示P操作,请求一个资源,第一个参数表示信号量下标,中间参数表示请求一个资源,最后一个参数表示如果进程结束则直接释放资源
$sem->op(0,-1,SEM_UNDO);
# 该操作表示V操作,释放一个资源
$sem->op(0,1,SEM_UNDO);
# 移除信号量集,如果不移除,则信号量会一直留在系统中
$sem->remove() if defined $sem;

Linux系统中使用ipcs -a命令可以查看当前系统中所有的信号量及共享内存段等使用。有些时候程序意外终止,信号量未释放,那么就可以使用该命令查看信号量,并使用ipcrm -s semid移除用semid标识的信号。

完整代码如下:

#!/bin/perl
use strict;
use IPC::Semaphore;
use IPC::SysV qw(IPC_PRIVATE S_IRUSR S_IWUSR IPC_CREAT IPC_NOWAIT SEM_UNDO);

our $sem = IPC::Semaphore->new(IPC_PRIVATE, 1, S_IRUSR | S_IWUSR | IPC_CREAT);
$sem->setval(0,1);
# fork returns the child pid to parent, 0 to child or undef if failed to fork.
my $pid = fork();
die "fork failed" unless defined $pid;
if($pid > 0){
  $sem->op(0,-1,SEM_UNDO);
  my $i = 1000;
  while($i > 0){
    print "parent process i = $i\n";
    $i--;
  }
  $sem->op(0,1,SEM_UNDO);
}elsif($pid == 0){
  $sem->op(0,-1,SEM_UNDO);
  my $i = 1000;
  while($i > 0){
    print "child process i = $i\n";
    $i--;
  }
}
$sem->remove() if defined $sem;

输出结果如下,可以看到,两个进程时串行执行的,达到了进程同步的效果。

parent process i = 16
parent process i = 15
parent process i = 14
parent process i = 13
parent process i = 12
parent process i = 11
parent process i = 10
parent process i = 9
parent process i = 8
parent process i = 7
parent process i = 6
parent process i = 5
parent process i = 4
parent process i = 3
parent process i = 2
parent process i = 1
child process i = 1000
child process i = 999
child process i = 998
child process i = 997
child process i = 996
child process i = 995
child process i = 994
child process i = 993
child process i = 992
child process i = 991
child process i = 990
child process i = 989
child process i = 988
child process i = 987
child process i = 986
child process i = 985
child process i = 984
child process i = 983
child process i = 982
child process i = 981
child process i = 980
child process i = 979
YOLOv9原创自研:卷积魔改 | 一种新颖的风车形卷积(PConv)融合注意力机制,加强微弱小目标检测能力 为了进一步提升小目标检测能力,风车形卷积(PConv)融合注意力机制进一步提升小目标检测能力 阅读详情

相关推荐

OpenCv —— 检测车牌号(附完整源码)

OpenCv —— 检测车牌号

5568

Perl多进程技术在自动化测试中的应用

本文内容包括:Perl多进程自动化测试场景介绍应用Perl多进程技术到自动化测试脚本小结参考资料在IT产品系统测试的自动化项目中,经常有并行处理多个子任务的需求,为了提高测试效率,就需要用到多进程或者多线程编程。文章介绍了Perl多进程的用法和适用场景,以及Perl多进程多线程的关系。同时结合企业级IT产品系统测试的自动化特点,介绍了Perl多进程在这方面的应用。Perl多进程Perl多进程Perl语言是一种非常强大的脚本语言,其广泛应用于系统维护,CGI(CommonGatewayInterface)编程,数据库编程和自动化测试中。多任务和并发处理一度被看作是判定优异操作系统的一个特

西门子PLC伦茨变频器在恒张力收放卷控制中的核心算法调试实战

在工业自动化领域,特别是冶金、造纸、线缆等连续生产行业,恒张力控制是保障产品质量和生产效率的关键技术。其核心原理在于通过实时计算变化的卷径,动态调整电机转矩,以维持材料张力的恒定。这一过程通常涉及闭环控制系统,由PLC作为计算指挥核心,变频器作为高精度执行单元。从技术价值看,它解决了卷绕过程中因直径变化导致的张力波动难题,直接关系到材料的平整度、拉伸均匀性及断带风险。典型的应用场景包括钢带收卷、薄膜印刷和电缆成缆等连续生产线。本文以经典的西门子S7-200 SMART PLC伦茨SPW420变频器组合为

weixin_33971977的博客 347

Perl多进程

本文关于Perl进程的内容主体来自于《Pro Perl》的第21章。 创建新进程 Perl中可以使用fork函数来创建新的进程,它会调用操作系统的fork系统调用来创建新进程。 fork是Unix系统中的函数,在Windows中不原生支持fork。但从Perl 5.8开始,Perl提供了一个模拟的fork使其可以无视平台的差异,它是使用Perl解释器线程来实现的fork,因为解释器线程不自动共享数...

weixin_30338743的博客 623

perl中创建多进程

本次项目中为了提高软件的运行效率,需要对pptx文件进行异步解压,通过运行发现Windows下多进程执行异常(调用fork函数创建子进程), 调用exe执行奔溃。其他非Windows平台好像没有这个问题。 解决方法: 在Windows下可以使用Win32::Process模块创建子进程,...

weixin_30466421的博客 353

perl实现多进程的操作

并行对多个节点进行操作处理

haiqinma的专栏 2186

Perl多进程实战

转自http://bbs.scmroad.com/viewthread.php?tid=3917perl作为一种解释性的语言,很受广大系统管理员的欢迎,好处么就不多说了,坏处也有不少,例如对线程的支持,就一直不咋地,所以大多数情况下,我们都需要多个进程,来帮助我们完成工作,闲话少

ace_fei的专栏 2747

Perl 多进程多线程编程

PERL 多进程多线程编程能大大加快程序执行效率(将一个任务分割成若干小任务并行处理)。要进行多进程多线程编程则分别需要两个模块, fork()和Threads,然而fork()则为PERL内置函数,因此,只需安装Threads模块(如需变量共享,还需安装Thread::Shared模块)。安装方法如下:     1)Win+R, 打开运行:                    2)在

海云之家 1万+

perl信号量实现进程间通信

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

weixin_33860553的博客 237

代码干货 | perl信号量实现进程间通信

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

CS13522431352的博客 761

Perl多进程实践——fork

perl作为一种解释性的语言,很受广大系统管理员的欢迎,好处么就不多说了,坏处也有不少,例如对线程的支持,就一直不咋地,所以大多数情况下,我们都需要多个进程,来帮助我们完成工作,闲话少说,上代码。 #!/usr/bin/perl # test_proc.pl # test multi process # create by lianming: 2009-08-12 use strict;

1289

Perl进程间数据共享

本文介绍的Perl进程间数据共享内容主体来自于《Pro Perl》的第21章。 IPC简介 通过fork创建多个子进程时,进程间的数据共享是个大问题,要么建立一个进程间通信的通道,要么找到一个两进程都引用的共享变量。本文将介绍Unix IPC的近亲System V IPC:message queues(消息队列)、semaphores(信号量)和shared memory-segments(共享内...

weixin_30788619的博客 552

IPC 在Perl中的应用

IPC就是用来进程间通讯用的东东,linux下,分为三类:消息队列、信号量、共享内存,在linux下,用ipcs命令就可以看到当前系统已经 创建的 ipc,ipcrm,可以删除已经创建的ipc,当然,要跟id的。既然它分为三类,那就要分三种类型来做讲解了。      首先是消息队列。消息队列比较简单,就是把数据放到队列里面,按照先进先出,后进后出的序列来。消息队列用的人已经很少了,它的大部分功能

MyDriverC 1128

Perl 网络编程socket练习(二)

前面的服务端程序由于是单一进程。所以进入循环后无法处理第二个客户端的连接请求。 下面,测试多进程:

Jianblog's VED 850

Perl语言的信号量

信号量作为并发控制的重要工具,在多进程多线程的环境中发挥着关键作用。Perl语言通过提供IPC模块,使得程序员可以方便地实现信号量机制,从而有效地解决共享资源的竞争问题。通过本文的理解,希望读者能够掌握信号量的基本原理,并能够在Perl中灵活运用,从而在并发程序设计中写出高效、安全的代码。信号量不仅在理论上具有重要性,在实际的系统编程和应用开发中同样扮演着不可或缺的角色。

2501_91024643的博客 734

掌握Perl并发:线程进程编程全攻略

并发编程是让程序能够同时执行多个任务的编程范式。在Perl中,可以通过多线程多进程两种方式实现并发。

2401_85743969的博客 1711

Perl中如何派生多进程 -- fork函数

这个函数当前在学校没有搞懂, 刚从学校出来时也没搞懂, 不会用他来写多线程程序. 今天有人问我在Perl中如何进行多进程编程, 去Google了一把, 发现境界好象比以前高了, 因为感觉上懂了一些了. 下面是写的一个例子: #!/usr/bin/perl#my $pid = fork();if (!defined($pid)){   print ("Fork process failured!/n

博青港湾-技术空间 4451

Perl多进程实战之一

perl作为一种解释性的语言,很受广大系统管理员的欢迎,好处么就不多说了,坏处也有不少,例如对线程的支持,就一直不咋地,所以大多数情况下,我们都需要多个进程,来帮助我们完成工作,闲话少说,上代码。 #!/usr/bin/perl # test_proc.pl # test multi process # create by  lianming: 2009-08-12 use st

boyishachang的专栏 515

Project of Mono-Chip Computers.zip

课设所涉及到的proteus文件和keil文件都在其中,下载即可用。功能:5位独立按键中断;LCD1602显示(年月日星期时分秒);DS1302时钟芯片;两路闹钟设置;AT89S52基本电路图。

上一篇: Linux内建命令及Bash Shell
下一篇: Linux rename
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值