system函数的问题

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qqwx_1986/article/details/8137723

最近碰到这样一个问题:

进程退出了,进程某个监听的端口还在监听状态,这个进程比较特殊,用system("start ")命令打开了其他的一些进程,然后该进程退出,用netstat发现该进程pid还在监听一个端口,但是任务管理器看不到这个进程pid了,然后把system打开的所有进程都关掉,我中间一个一个关发现直到最后一个进程关掉,这个端口才解除监听

最后调试跟踪system函数,发现system函数里面最终还是调用了

BOOL WINAPI CreateProcess(
  __in          LPCTSTR lpApplicationName,
  __in_out      LPTSTR lpCommandLine,
  __in          LPSECURITY_ATTRIBUTES lpProcessAttributes,
  __in          LPSECURITY_ATTRIBUTES lpThreadAttributes,
  __in          BOOL bInheritHandles,
  __in          DWORD dwCreationFlags,
  __in          LPVOID lpEnvironment,
  __in          LPCTSTR lpCurrentDirectory,
  __in          LPSTARTUPINFO lpStartupInfo,
  __out         LPPROCESS_INFORMATION lpProcessInformation
);

这个函数调用的cmd.exe,而CreateProcess的参数bInheritHandles是填的TRUE,参照msdn对bInheritHandles的解释

If this parameter TRUE, each inheritable handle in the calling process is inherited by the new process. If the parameter is FALSE, the handles are not inherited. Note that inherited handles have the same value and access rights as the original handles.

如果该参数为TRUE那么子进程继承父进程所有能继承的句柄,而且拥有父进程同样的句柄值和权限


所以这个bug的产生的原因大概也明了了,我这个进程所监听的端口socket被继承到cmd.exe中,然后cmd通过start(start里面应该也是调用的CreateProcess()而已也是继承参数为TRUE)继承到了我start打开的进程,这也是为什么直到我关闭最后的子进程该端口才关闭


linux下的system好像也有同样的问题,猜测应该也是fork的参数问题


解决方案

(1) 自己写system

(2) 自己写一个代理客户端,客户端一个for循环把所有的socket给关了,可以根据实际情况关闭轮询的最大个数(具体可以搜索linux和windows下socket ID分配策略)

#ifndef _WIN32
for(int i=3;i<128;i++)
{
close(i);
}
#else
for(int i=0;i<1024;i++)
{
closesocket(i);
}
#endif
system(cmd);




展开阅读全文

system函数阻塞问题 讨论

07-08

去年做了一个数据采集箱的项目。在调试过程中发现system函数容易出现阻塞,导致线程一直阻塞住。后来我单独写了一个main函数,来测试system函数。结果发现,system函数运行几十次到几千次后就可能会出现阻塞的情况。当时很费解,就自己实现了一个system函数(通过fork + execl 函数 实现),结果发现一样会出现阻塞的情况,后来跟踪后发现,问题出在fork函数。rnrn按说调用fork 函数会返回两次,分别返回父进程 和 子进程。我出现的情况是,父进程正常返回子进程的pid号,但是子进程没有返回。fork函数只返回了一次。 然后父进程就阻塞在waitpid这个函数这里了。通过ps命令,可以看到子进程是已经建立了,kill 子进程的pid后,waitpid函数可以返回了。rnrn我感觉像是fork函数出问题了,但是fork函数自己没法实现。rnrn系统内核是2.6.24.rn板子是arm平台的,主控是his3515.rnrn这个问题到现在还困扰着我。后来实在没办法,我就结合alarm函数来处理了,用自己重写的system函数,执行的时候,同时设定好alarm的超时时间,由超时函数处理,时间超过了预设的超时时间,就把子进程的pid杀掉,再重新执行。毕竟出现连续阻塞的概率还是很低的。rnrn现在这样虽然系统能够正常运行了,但终究觉得不怎么好,想弄明白到底什么原因导致的这个问题。rnrn想问问这边牛人们,有没有碰到过类似的问题,你们如何处理的呢?谢谢!rn 论坛

没有更多推荐了,返回首页