windows、linux创建子进程

本文介绍了在Windows和Linux环境下创建子进程的方法。Windows中主要使用CreateProcess API,通过设置不同参数来控制新进程的行为。而在Linux中,则利用fork()函数创建子进程,并通过execve()函数执行指定程序。

在windows下创建子进程较常用到的API就是CreateProcess,可以通过以下的方式启动一个新进程:

 

    STARTUPINFO si = {0};             
    PROCESS_INFORMATION pi = {0}; 
    si.cb = sizeof(STARTUPINFO);         //结构体大小
    GetStartupInfo(&si);                       //初始化结构
    si.wShowWindow = SW_HIDE;         //新进程不显示窗口
    si.dwFlags = STARTF_USESHOWWINDOW;  //令si.wShowWindow生效
    //关键步骤,CreateProcess函数参数意义请查阅MSDN 
    if (!CreateProcess( NULL,            //可执行文件名,为NULL时,通过szCmdLine提供
                               szCmdLine,     //命令行参数
                               NULL,             //指向一个SECURITY_ATTRIBUTES结构体,这个结构体决定是否返回的句柄可以被子进程继承。
                                                     //如果lpProcessAttributes参数为空(NULL),那么句柄不能被继承。 
                               NULL,             //指向一个SECURITY_ATTRIBUTES结构体,这个结构体决定是否返回的句柄可以被子进程继承。
                                                     //如果lpThreadAttributes参数为空(NULL),那么句柄不能被继承。 
                              FALSE,         //指示新进程是否从调用进程处继承了句柄
                              NULL,          //指定附加的、用来控制优先类和进程的创建的标志
                              NULL,          //指向一个新进程的环境块。如果此参数为空,新进程使用调用进程的环境
                              NULL,          //子进程的工作路径,当进程名为相对路径时,必须填写
                                &si,           //指向一个用于决定新进程的主窗体如何显示的STARTUPINFO结构体
                               &pi))          //指向一个用来接收新进程信息的PROCESS_INFORMATION结构体
    { 
        return false;
    } 

    WaitForSingleObject(pi.hProcess,INFINITE);   //等待子进程结束
    CloseHandle(pi.hThread);                             //关闭新进程的主线程
    CloseHandle(pi.hProcess);                            //关闭新进程

 

在linux下创建子进程:

    pid_t pid;
    if(( pid = fork()) == -1 )                                                 //创建子进程
    {
        exit(0);                                                                      //创建进程失败,退出程序
    } else if(pid == 0) {                                                        //子进程空间

        char *args[]={FileMonitor, "-fp", lmonitorList[num].lm_strDirectory,  NULL};
        if(execve(FileMonitor, args, NULL)< 0) {                        //在子进程中调用FileMonitor进程

           printf("execve ./wisFileMonitor -fp %s failed in the child process!/n", lmonitorList[num].lm_strDirectory);
            CREATE_THREAD(StartMonitorThread, (THREAD_PARAM) num); 
        }
    } else {                                                                         //父进程空间
        lmonitorList[num].lm_pid = pid;
        lmonitorList[num].lm_bstop=false;
    }

如果在创建子进程时,没有出现任何错误,fork函数将返回两次,一次在父进程中,另一次在子进程中。fork函数将新创建的子进程ID返回给父进程,并将0返回给子进程。

<think>好的,我现在需要解释一下“if __name__ == '__main__'防止Windows递归创建子进程”是什么意思。首先,我得回忆一下Python中这个常见结构的作用。 用户提到的“防止Windows递归创建子进程”应该和多进程编程有关。在Python中,当使用multiprocessing模块创建子进程时,特别是在Windows系统上,子进程会重新导入主模块。这可能导致代码在子进程中再次执行,如果不加以控制,可能会引发递归创建进程的问题,甚至进入无限循环。 所以,__name__ == '__main__'这个条件判断的作用就是确保其中的代码块只在直接运行该脚本时执行,而当脚本被作为模块导入时不会执行。在Windows系统中,由于子进程需要重新导入主模块,如果没有这个保护,子进程又会执行主模块中的代码,导致不必要的进程创建或者重复执行。 举个例子,假设有一个脚本使用了multiprocessing来创建子进程,如果在主模块中没有使用if __name__ == '__main__',那么当子进程创建时,会再次执行主模块中的代码,进而再次创建子进程,形成递归,最终可能导致程序崩溃或者资源耗尽。 因此,这个条件判断的作用是确保在多进程编程中,尤其是在Windows系统下,主进程的代码只在主程序中运行,避免子进程重复执行主模块的代码,从而防止递归创建子进程的问题。</think>当在Python中使用多进程编程(例如`multiprocessing`模块)时,Windows系统由于没有类似Unix的`fork()`机制,创建子进程时会重新导入主模块。如果不使用`if __name__ == "__main__"`保护主进程代码,会导致递归创建子进程的问题。以下是逐步解释: --- ### **1. 问题背景** 在Windows系统中: - 创建子进程时,Python会重新执行当前脚本(相当于重新`import`当前模块)。 - 若主进程代码(如创建子进程的代码)**未**被`if __name__ == "__main__"`保护,子进程在导入模块时会再次执行这些代码,导致无限递归创建子进程。 --- ### **2. 示例代码分析** 假设有以下未受保护的代码(`bad_example.py`): ```python from multiprocessing import Process def worker(): print("子进程工作") # 直接创建子进程(未受保护) p = Process(target=worker) p.start() p.join() ``` 当运行`bad_example.py`时: 1. 主进程创建子进程`p`。 2. 子进程会重新导入`bad_example.py`模块。 3. 子进程再次执行`p = Process(target=worker)`,触发新的子进程。 4. 新的子进程又会重复上述步骤,导致**无限递归**。 --- ### **3. 解决方案:`if __name__ == "__main__"`** 通过将主进程代码包裹在`if __name__ == "__main__"`中,确保代码仅在**直接运行脚本**时执行,而**被导入时不执行**。 修正后的代码(`good_example.py`): ```python from multiprocessing import Process def worker(): print("子进程工作") if __name__ == "__main__": # 关键保护 p = Process(target=worker) p.start() p.join() ``` 此时: - 主进程直接运行脚本时,`__name__`为`"__main__"`,代码执行。 - 子进程导入模块时,`__name__`为模块名(`good_example`),代码**不执行**,避免递归。 --- ### **4. 总结** - **作用**:`if __name__ == "__main__"`确保主进程代码仅在直接运行脚本时执行。 - **必要性**:在Windows多进程编程中,防止子进程递归执行主模块代码。 - **跨平台建议**:即使在其他系统(如Linux)中,也建议始终添加此保护,以保证代码可移植性。 --- ### **5. 扩展:验证`__name__`的值** ```python print("当前模块的 __name__ 是:", __name__) ``` - 直接运行脚本时输出:`__main__` - 被其他模块导入时输出:模块的文件名(如`my_module`) 通过这种方式,可以精确控制代码的执行逻辑。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值