LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 1733|回复: 9

晕了,很简单的fork()都搞不定。。

[复制链接]
发表于 2004-1-2 17:08:19 | 显示全部楼层 |阅读模式
R# cat child
#!/usr/bin/perl -w
if( ( $a=fork() ) >0) { #这是比较fork()的子进程的ID是否大于零,调用fork()一次,但返回两次。
print "no\n" ;
}else {
print "yes\n" ; }
R# perl child
Name "main::a" used only once: possible typo at child line 2.
yes
no
R#
:confused: :help
发表于 2004-1-2 17:23:21 | 显示全部楼层
#!/usr/bin/perl -w
if(fork()>0)  {
print "no\n" ;
}else {
print "yes\n" ; }
##這樣好嗎 ;)
 楼主| 发表于 2004-1-2 17:41:09 | 显示全部楼层
:thank
看来不能同时幅值
在C就行。
  pid_t pid;
  if((pid=fork())>0)

想不到这里PERL比C还限制.
发表于 2004-1-2 18:28:24 | 显示全部楼层
什麼限制?
 楼主| 发表于 2004-1-2 19:35:08 | 显示全部楼层
就是不能在条件判断那里同时赋值,C源码:
R# cat child.c
#include <sys/types.h>
#include <stdio.h>
/* #include <process.h> */
int main(void)
{
  pid_t pid;
  if((pid=fork())>0)
   printf(" parent\n");
  else
   printf("child\n");
printf("%d\n",pid);
exit (0);
}
R# gcc child.c
R# ./a.out
child
0
parent
1189
R#
发表于 2004-1-2 20:00:07 | 显示全部楼层
最初由 devel 发表
:thank
看来不能同时幅值
在C就行。
  pid_t pid;
  if((pid=fork())>0)

想不到这里PERL比C还限制.


the return value are different for System call in Perl from C.

From man perlfunc:

   In general, functions in Perl that serve as wrappers for
       system calls of the same name (like chown(2), fork(2),
       closedir(2), etc.) all return true when they succeed and
       "undef" otherwise, as is usually mentioned in the descrip-
       tions below. This is different from the C interfaces,
       which return "-1" on failure.   Exceptions to this rule are
       "wait", "waitpid", and "syscall".  System calls also set
       the special $!  variable on failure.  Other functions do
       not, except accidentally.
发表于 2004-1-3 00:25:57 | 显示全部楼层
perl不是说的很清楚吗,
Name "main::a" used only once: possible typo at child line 2.
因为你的$a只赋了一次值,后来就没有用过,所以是一个没用的变量,你输出的时候用一下就行了,比如print "no, $a\n";
 楼主| 发表于 2004-1-3 22:27:33 | 显示全部楼层
原来是这样:thank :thank ,E文看得懂,就是不知道它隐含的正确方法。
发表于 2004-1-4 05:57:51 | 显示全部楼层
ibinary给的解释对,我还真没注意,呵呵。

不过我看man ,用你的方法直接给fork()函数赋值有问题,因为回值是"true" and
"undef",特别是这个"undef",好麻烦的?!不是吗??下面的方法把缺陷给补上了.

我也上网看了看有关题目,感觉还是满有趣的,大家看看,原来网址是:
http://www.die.net/doc/linux/man/man1/perlfork.1.html


The "open(FOO, "|-")" and "open(BAR, "-|")" constructs are not yet implemented. This limitation can be easily worked around in new code by creating a pipe explicitly. The following example shows how to write to a forked child:

    # simulate open(FOO, "|-")
    sub pipe_to_fork ($) {
        my $parent = shift;
        pipe my $child, $parent or die;
        my $pid = fork();
        die "fork() failed: $!" unless defined $pid;
        if ($pid) {
            close $child;
        }
        else {
            close $parent;
            open(STDIN, "<&=" . fileno($child)) or die;
        }
        $pid;
    }



    if (pipe_to_fork('FOO')) {
        # parent
        print FOO "pipe_to_fork\n";
        close FOO;
    }
    else {
        # child
        while (<STDIN>) { print; }
        close STDIN;
        exit(0);
    }


And this one reads from the child:


    # simulate open(FOO, "-|")
    sub pipe_from_fork ($) {
        my $parent = shift;
        pipe $parent, my $child or die;
        my $pid = fork();
        die "fork() failed: $!" unless defined $pid;
        if ($pid) {
            close $child;
        }
        else {
            close $parent;
            open(STDOUT, ">&=" . fileno($child)) or die;
        }
        $pid;
    }



    if (pipe_from_fork('BAR')) {
        # parent
        while (<BAR>) { print; }
        close BAR;
    }
    else {
        # child
        print "pipe_from_fork\n";
        close STDOUT;
        exit(0);
    }
发表于 2004-1-4 07:59:24 | 显示全部楼层
emm,undef,这个确实麻烦,一开始没考虑这个
自己编程的时候用fork比较少,不太熟,又看了一下书,感觉这样比较好:

  1. #! /usr/bin/perl -w

  2. if(!defined($pid = fork())){
  3.   die "fork() error: $!";
  4. }elsif($pid == 0){
  5.   print "child\n";
  6. }else{
  7.   waitpid($pid, 0);
  8.   print "parent\n";
  9. }
复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表