我是perl中多进程编程过程的新手。 我试图编写一个基于多线程多进程的应用程序,该应用程序给了我“ SEGMENTATION FAULT”。 该程序很简单。 首先,PARENT PROCESS会生成一些进程(使用fork),并且每个进程都会在一段时间后运行,并在随机延迟后死亡。 同时,父进程产生相等数量的线程以侦听每个新创建的子进程。 我正在使用管道在派生的进程和主进程产生的线程之间进行通信。 这里的想法是,当一个进程死亡时,应该立即使用相同的管道生成另一个新进程,并因此在子例程调用之后产生无限的while循环。 在一段时间内,这可以正常工作,但是突然出现分段错误。 如何调试这种情况? 我的PERL版本是5.8.8

#!/usr/local/bin/perl -w
use strict;
use threads;
use threads::shared;
use IO::Pipe;
use warnings;
print "Starting main program\n";
my $ACTIVE_PROCESSES :shared =0;
my $MAX_PROCESSES:shared =5,
my %process_state_list : shared;
my %process_id_list : shared;
$SIG{CHLD} = sub { wait };
my $GLOBAL_COUNT=0;
my @pipe_array=&share([]);
&init_pipes();
&spawn_process();
while(1)
{
for (my $i=0;$i<$MAX_PROCESSES;$i++)
 {
    if ($process_state_list{$i} =~ /INACTIVE/)
    {
        print "Found Process $i is inactive\n"; 
    spawn_next_process($i);
    }
 }
}
print "End of main program from $$\n";

sub init_pipes
{
my $i=0;
for ($i=0;$i< $MAX_PROCESSES; $i++)
  { 
    $pipe_array[$i] = IO::Pipe->new();
    $process_state_list{$i}="INACTIVE";
    print "Pipe $i initialized to $pipe_array[$i]\n";
  }
}
sub spawn_process
{
print "Spawn process called..\n";
while ( $ACTIVE_PROCESSES < $MAX_PROCESSES) 
   {
      $GLOBAL_COUNT++;
      PARENT_create_child();
      PARENT_create_child_listener();
   }
}

sub PARENT_update_child_map
{
my ($i,$cmd)=@_;
if ($cmd =~ /CREATE/)
  {
    for (my $j=0;$j<$MAX_PROCESSES;$j++)
    {
        print "j is $j and process_state_list is $process_state_list{$j}\n";
    if ($process_state_list{$j}=~ /INACTIVE/)
    {
        $process_state_list{$j}="ACTIVE";
        return $j;
    }
    }
  }
}
sub PARENT_create_child()
{
    for (my $i=0;$i<$MAX_PROCESSES;$i++)
     {
        print"--------FORKING CHILD from MAIN PROCESS MAIN PID $$\n";
        my $local_pr_id = PARENT_update_child_map($i,"CREATE");
        my $pid = fork() ;
                if ($pid) {
        # parent
        print "For local_pr_id $local_pr_id CHILD is $pid, PARENT $$\n";
        $ACTIVE_PROCESSES++;
                } 
        elsif ($pid == 0) {
                # child
                child_activator($local_pr_id);
        exit 0;
        } else {
                die "couldnt fork: $!\n";
        }
      }
}
sub PARENT_create_child_listener()
{
print"--------THREADING CHILD LISTENER FROM--$$--\n";
my $i;
for ($i=0;$i<$MAX_PROCESSES;$i++)
{
my $worker_thread = threads->create(sub {\&read_from_child($i)});
$worker_thread->detach();
}
}
sub read_from_child
{
    my $th=threads->self();
    print"--------NOW THREADING:$th->tid()\n";
    my ($pipe_index)=shift;
    print "pipe_index is $pipe_index\n";
    ($pipe_array[$pipe_index])->reader();
    my $filehandle=$pipe_array[$pipe_index];
    while ( <$filehandle> ) {
        my $msg=$_;
        print "CHILD LISTENER received: $msg And current Process ID is $$\n";
        PARENT_msg_from_child($msg);
    }
    print "Exiting read_from_child from $$\n";
}
sub PARENT_msg_from_child()
{
my $msg=shift;
if ($msg =~ /IPC_MSG_PROCESS_EXIT/)
  {
   PARENT_handle_IPC_MSG_PROCESS_EXIT($msg);
  }
if ($msg=~ /IPC_MSG_PROCESS_START/)
  {
   PARENT_handle_IPC_MSG_PROCESS_START($msg);
  }
}
sub PARENT_handle_IPC_MSG_PROCESS_START
{
my $msg=shift;
my @split_array=split(":",$msg);
my $local_pr_id=$split_array[1];
my $process_id=$split_array[2];
$process_state_list{$local_pr_id}="ACTIVE";
$process_id_list{$local_pr_id}=$process_id;
}
sub PARENT_handle_IPC_MSG_PROCESS_EXIT
{
my $msg=shift;
my @split_array=split(":",$msg);
my $local_pr_id=$split_array[1];
print "------------------------\n";
$ACTIVE_PROCESSES--;
$process_state_list{$local_pr_id}="INACTIVE";
my $exists = kill 0, $local_pr_id;
kill(9,$process_id_list{$local_pr_id}) if $exists;
print "Process $process_id_list{$local_pr_id} terminated\n";
}
sub spawn_next_process
{
my $local_pr_id= shift;
print"--------FORKING NEXT CHILD from MAIN PROCESS MAIN PID $$\n";
        $process_state_list{$local_pr_id}="ACTIVE";
        my $pid = fork() ;
                if ($pid) {
        # parent
        print "For local_pr_id $local_pr_id CHILD is $pid, PARENT $$\n";
        $ACTIVE_PROCESSES++;
                } 
        elsif ($pid == 0) {
                # child
                child_activator($local_pr_id);
        exit 0;
        } else {
                die "couldnt fork: $!\n";
        }
}
#################C H I L D -- S E C T I O N####################
sub child_activator {
        sleep (7);
        my $local_pr_id=shift;
        print "In child activator $$\n";
        my $filehandle=$pipe_array[$local_pr_id] ;
        ($pipe_array[$local_pr_id])->writer();
        my $message="IPC_MSG_PROCESS_START:$local_pr_id:$$:";
    print "Sending $message\n";
        print $filehandle $message
            or die "Failed to pass message to child: $!";
        my $random_number = rand();
        sleep(4*$random_number);
        print "Now in child process $$\n";
        print "local_pr_id is $local_pr_id\n";
        $message="IPC_MSG_PROCESS_EXIT:$local_pr_id:";
        print "Sending $message\n";
        print $filehandle $message
            or die "Failed to pass message to child: $!";
}
################# E N D - C H I L D - S E C T I O N###########

我从中得到的输出非常奇怪

<I>xl-mat-02{userxxx}141: perl run_tc.pl
Starting main program
Pipe 0 initialized to IO::Pipe=GLOB(0x169c4830)
Pipe 1 initialized to IO::Pipe=GLOB(0x168632a0)
Pipe 2 initialized to IO::Pipe=GLOB(0x169c4af0)
Pipe 3 initialized to IO::Pipe=GLOB(0x169c4bb0)
Pipe 4 initialized to IO::Pipe=GLOB(0x169c4c70)
Spawn process called..
--------FORKING CHILD from MAIN PROCESS MAIN PID 1520
j is 0 and process_state_list is INACTIVE
For local_pr_id 0 CHILD is 1598, PARENT 1520
--------FORKING CHILD from MAIN PROCESS MAIN PID 1520
j is 0 and process_state_list is ACTIVE
j is 1 and process_state_list is INACTIVE
For local_pr_id 1 CHILD is 1599, PARENT 1520
--------FORKING CHILD from MAIN PROCESS MAIN PID 1520
j is 0 and process_state_list is ACTIVE
j is 1 and process_state_list is ACTIVE
j is 2 and process_state_list is INACTIVE
For local_pr_id 2 CHILD is 1600, PARENT 1520
--------FORKING CHILD from MAIN PROCESS MAIN PID 1520
j is 0 and process_state_list is ACTIVE
j is 1 and process_state_list is ACTIVE
j is 2 and process_state_list is ACTIVE
j is 3 and process_state_list is INACTIVE
For local_pr_id 3 CHILD is 1601, PARENT 1520
--------FORKING CHILD from MAIN PROCESS MAIN PID 1520
j is 0 and process_state_list is ACTIVE
j is 1 and process_state_list is ACTIVE
j is 2 and process_state_list is ACTIVE
j is 3 and process_state_list is ACTIVE
j is 4 and process_state_list is INACTIVE
For local_pr_id 4 CHILD is 1602, PARENT 1520
--------THREADING CHILD LISTENER FROM--1520--
--------NOW THREADING:threads=SCALAR(0x16abfef0)->tid()
pipe_index is 0
--------NOW THREADING:threads=SCALAR(0x16b95010)->tid()
pipe_index is 1
--------NOW THREADING:threads=SCALAR(0x2aaaac0fdfb0)->tid()
pipe_index is 2
--------NOW THREADING:threads=SCALAR(0x2aaaac1e2770)->tid()
pipe_index is 3
--------NOW THREADING:threads=SCALAR(0x2aaaac2c7210)->tid()
pipe_index is 4
In child activator 1598
Sending IPC_MSG_PROCESS_START:0:1598:
In child activator 1599
Sending IPC_MSG_PROCESS_START:1:1599:
In child activator 1600
Sending IPC_MSG_PROCESS_START:2:1600:
In child activator 1601
Sending IPC_MSG_PROCESS_START:3:1601:
In child activator 1602
Sending IPC_MSG_PROCESS_START:4:1602:
Now in child process 1599
local_pr_id is 1
Now in child process 1600
local_pr_id is 2
Sending IPC_MSG_PROCESS_EXIT:2:
Sending IPC_MSG_PROCESS_EXIT:1:
Now in child process 1601
local_pr_id is 3
Sending IPC_MSG_PROCESS_EXIT:3:
***Segmentation fault***
xl-mat-02{userxxx}142: Now in child process 1598
local_pr_id is 0
Sending IPC_MSG_PROCESS_EXIT:0:
Now in child process 1602
local_pr_id is 4
Sending IPC_MSG_PROCESS_EXIT:4:</I>

我无法确定为什么会出现分段错误。 就像我说的那样,我是多进程环境编程的新手。 所以我可能错过了一些非常基本的知识。 任何帮助,将不胜感激。 即使您在这种情况下有一些关于分段错误的基本技巧,也请让我知道,因为我一无所知!

  ask by Utkarsh Kumar translate from so

本文未有回复,本站智能推荐:

1回复

匿名段上的boost :: interprocess内存分配器

我正在尝试使用类似mmap的段来分配stl容器上的对象,因为我正在使用boost :: interprocess,它提供了内存映射,分配器和匿名内存映射支持。 有点像这样 我的问题是这里的anonymous_shared_memory函数返回的内容看起来是半映射文件和半共享内存(对mm
2回复

Linux多进程通信多个生产者一个消费者

我需要在C ++上构建类似客户端服务器应用程序的东西。 目标是跟踪具有多个线程的多个进程(跟踪函数执行),并将此数据收集到按线程ID划分的文件中。 现在,我已经在POSIX消息队列上实现了这一点(服务器侦听队列并从生产者那里收集数据),但是工作非常慢。 关于在Linux平台(C ++语
2回复

性能 - 多线程或多进程应用程序

为了在Linux上开发高度网络密集型服务器应用程序,首选哪种架构? 这个想法是这个应用程序通常在具有多个核心(虚拟或物理)的机器上运行。 考虑到性能是关键标准,选择多线程应用程序还是采用多进程设计的应用程序更好? 我知道共享资源和同步以从多个进程访问这些资源是很多编程开销,但如前所述,整体
2回复

如何在Perl中实现信号量线程通信?

我的Perl脚本需要同时运行多个线程... ...并且此类线程需要从Web获取一些信息,因此使用HTTP::Async 。 但是有些线程只有在其他线程这样说时才需要访问web。 可能有一个或多个线程在等待 “go”信号,并且可能存在一个或多个线程,这样的“go”信号可以发
1回复

如何在Perl中的对象之间共享公共线程池?

我一直在尝试将Perl Monks( http://www.perlmonks.org/?node_id=735923 )上的第一个答案扩展到无用的线程模型。 我不断遇到无法传递代码引用的问题 在我的超类中,我将线程池定义为一个包变量,以便可以在子类之间共享它: 现在为子类。
3回复

如何在内存使用量较大的Perl守护程序中处理多个套接字?

我使用IO :: Socket :: INET使用Perl创建了一个客户端 - 服务器程序。 我通过基于CGI的站点访问服务器。 我的服务器程序将作为守护程序运行,并将接受多个同时连接。 我的服务器进程占用大约100MB的内存空间(9个大型阵列,许多阵列......)。 我希望这些哈希驻
4回复

Perl有多处理模块吗?

Perl有多处理模块吗? 与Python的多处理模块提供的功能类似的东西。 我知道我可以使用Perl构建类似的功能,但我正在寻找已经实现的功能。
1回复

Perl,儿童和共享数据

我正在使用一个包含大量网址(数万个)的数据库。 我正在尝试多线程一个解析器,它只是尝试解析一个给定的域。 成功时,它会将结果与数据库中当前的结果进行比较。 如果不同,则更新结果。 如果失败,它也会更新。 当然,这将产生过多的数据库调用。 为了澄清我对实现某种形式的异步负载分配的最
1回复

如何遍历管道中的数据?

我发现一些代码可以在Perl中2个进程通过管道进行通信。 例: 现在我有以下问题: 是否可以使读取器从管道中读取,然后像循环一样阻塞直到新数据从管道中出来? 如果是,当父进程没有要发送的数据时,杀死子进程的方法是什么? 每个程序有多少个打开的读/写管道有限制吗
1回复

如何从子进程中获取值?

我有一个脚本,在某些方面我分叉一些进程来完成一个任务,主进程等待所有孩子完成。 到目前为止一切都好。 问题:我有兴趣获得每个子进程在处理它必须做的事情时花费的最长时间。 我现在所做的只是查看日志,其中我打印了子进程所执行的每个操作所花费的时间,并尝试或多或少地计算出时间。 我知道