免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 4034 | 回复: 4
打印 上一主题 下一主题

windows 下 fork 有哪些问题啊? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-12-04 14:32 |只看该作者 |倒序浏览
以前win下也就简单用用 fork,感觉还好,没遇到什么问题。

今天用 POE 实现个 tcp server, 因为考虑到对 server 端而言,每个 session 本身也会有比较复杂的状态机,有些操作,甚至会有非常耗时的block操作,
因此考虑父进程就用POE::Wheel::ListenAccept() 处理每个socket连接,而对收到的每个 client 连接,就 fork 一个进程,在 子进程 中 create 一个POE session

代码稍微改了下,感觉没啥错误了,win下一执行,结果发现每个 client 都不能正常工作, cpu一会儿就到 100%,一开始还以为是 有什么逻辑错误,实在查不出来后,直接脚本 copy 到 linux 中,运行,毫无问题,残念……浪费了我一上午时间!

fork 的代码就这段:


  1. sub accept_client {
  2.   my ($kernel, $heap, $remote_sock, $remote_addr, $wheel_id) = @_[KERNEL, HEAP, ARG0..ARG2];
  3.   my ($peerport, $packed_ip) = sockaddr_in($remote_addr);
  4.   my $client_ip = inet_ntoa($packed_ip);
  5.   print "SERVER: recieved a connection from $client_ip:$peerport\n";
  6.   my $pid;
  7.   if( $pid = fork() ) {
  8.     print "SERVER: Create a sub process $pid for $client_ip:$peerport, and return!\n";
  9.     return 0;
  10.   }elsif(defined $pid) {
  11.     delete $_[HEAP]->{listener}; # delete wheel which copy from main process
  12.     $|++;
  13.     POE::Session->create(
  14.       inline_states => {
  15.         _start        => \&start_child,
  16.         socket_input  => \&socket_input,
  17.         socket_failed => \&socket_failed,
  18.         check_shutdown => \&check_shutdown,
  19.         interrupt      => \&process_interrupt,
  20.       },
  21.       args => [ $remote_sock, $client_ip, $peerport ],
  22.     );
  23.   }else {
  24.     print "return undef, can't fork, $!\n";
  25.     return;
  26.   }
  27. }
复制代码


请教下大家,win 下 fork 会有哪些问题? 或者还是上面代码确实有问题?

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
2 [报告]
发表于 2009-12-04 15:40 |只看该作者
POE 里面不能这么用 fork,
先不说是不是 windows 的问题。

根据我的工程实践经验,
1,尽量把 block 都变成 nonblock
2,实在没法变的,用 POE::Whell::Run 代替 fork,不过貌似只能创建 64 个。
还是得用非阻塞啊。

论坛徽章:
0
3 [报告]
发表于 2009-12-04 17:08 |只看该作者
谢谢指导!
因为是要把以前单机版的脚本,变为 cs 模式,不用每个pc都去装脚本环境,单机版的脚本真正 block 多的,实际是一个非常大的函数库,改的话,实在是个不小的工程……

之前没怎么考虑 POE::Whell::Run ,因为之前用了一个 Wheel::ReadWrite ,忘了也是可以用 两个 Whell 的,这样貌似更方便了,先试试!

另外注意到  POE::Whell::Run 的实现,也是用的 fork 来处理的,flw 也说 “POE 里面不能这么用 fork”, 请教下 POE 里面,我如上方式,使用 fork 会有什么问题出现吗?

对父进程 POE::Wheel::ListenAccept 将每个 accept 的 socket 传入到 fork 出的子进程后,然后close socket,而子进程先删除copy自父进程的POE::Wheel::ListenAccept,然后和 socket 通信,socket 通信结束后,直接 exit(0)。

这个过程,初步看没感觉有什么逻辑问题,linux下尝试运行也挺稳定的,有什么隐患吗?

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
4 [报告]
发表于 2009-12-04 17:14 |只看该作者
你可以看看 POE::Whell::Run 的实现,
不过话说回来,它有很多 BUG,我都改过了,但是没提交到 CPAN。晕。

论坛徽章:
1
未羊
日期:2014-09-08 22:47:27
5 [报告]
发表于 2009-12-05 10:26 |只看该作者
flw老大,你怎么不提交呢?是CPAN不让你提交,还是你懒?
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP