pu油墨,绞车滚筒,十堰二手房出售
程序每次执行时,操作系统都会创建一个新进程来运行程序指令。进程中可调用os.fork,要求操作系统新建一个子进程.[windowsc系统中,os模块没有os.fork函数]。
每个进程都有一个不重复的进程id号。或称pid,它对进程进行标识。子进程与父进程完全相同,子进程从父进程继承了多个值的拷贝。如全局变量和环境变量。fork后,子进程接收返回值0,而父进程接收子进程的pid作为返回值
os.
fork
()fork a child process. return 0
in the child and the child’s process id in the parent. if an error occurs oserror is raised.
note that some platforms including freebsd <= 6.3 and cygwin have known issues when using fork() from a thread.
availability: unix > 仅支持基于unix核心的系统
os.getpid() 返回进程pid
os.getppid() 返回父进程pid
# -*-coding:utf-8-*- import os import time print('before calling') p = os.fork() # 主进程,子进程同时向下执行 print('after calling') if p == 0: print('执行子进程, pid={} ppid={} p={}'.format(os.getpid(), os.getppid(), p)) else: print('执行主进程, pid={} ppid={} p={}'.format(os.getpid(), os.getppid(), p))
[root@192 ~]# python fork.py before calling after calling 执行主进程, pid=1629 ppid=1572 p=1630 after calling 执行子进程, pid=1630 ppid=1629 p=0
# -*-coding:utf-8-*- import os import time print('before calling') p = os.fork() # 主进程,子进程同时向下执行 print('after calling') if p == 0: print('执行子进程, pid={} ppid={} p={}'.format(os.getpid(), os.getppid(), p)) time.sleep(1) print('执行子进程, pid={} ppid={} p={}'.format(os.getpid(), os.getppid(), p)) else: print('执行主进程, pid={} ppid={} p={}'.format(os.getpid(), os.getppid(), p))
[root@192 ~]# python fork.py before calling after calling 执行主进程, pid=1648 ppid=1572 p=1649 after calling 执行子进程, pid=1649 ppid=1648 p=0 [root@192 ~]# 执行子进程, pid=1649 ppid=1 p=0
# -*-coding:utf-8-*- import os import time p = os.fork() if p == 0: time.sleep(10) print('执行子进程, pid={} ppid={} p={}'.format(os.getpid(), os.getppid(), p)) else: time.sleep(5) print('执行主进程, pid={} ppid={} p={}'.format(os.getpid(), os.getppid(), p))
[root@192 ~]# python fork.py & ### 后台执行python代码 [1] 1693 ### 五秒前,查看进程信息:主进程为1693,子进程为1694 [root@192 ~]# ps aux | grep fork.py root 1693 0.0 0.1 125432 4592 pts/0 s 21:23 0:00 python fork.py root 1694 0.0 0.0 125432 2748 pts/0 s 21:23 0:00 python fork.py root 1696 0.0 0.0 112704 980 pts/0 s+ 21:23 0:00 grep --color=auto fork.py [root@192 ~]# 执行主进程, pid=1693 ppid=1572 p=1694 (此为程序打印信息,说明主进程已执行完) [1]+ done python fork.py ### 五秒后,主进程执行完毕,查看进程信息:只剩子进程1694 [root@192 ~]# ps aux | grep fork.py root 1694 0.0 0.0 125432 2748 pts/0 s 21:23 0:00 python fork.py root 1698 0.0 0.0 112704 980 pts/0 s+ 21:23 0:00 grep --color=auto fork.py [root@192 ~]# 执行子进程, pid=1694 ppid=1 p=0 (此为程序打印信息,说明子进程已执行完。 *注意,这里ppid是1) ### 十秒后,子进程执行完毕,子进程结束 [root@192 ~]# ps aux | grep fork.py root 1708 0.0 0.0 112704 980 pts/0 s+ 21:23 0:00 grep --color=auto fork.py
若子进程比父进程先结束,而父进程又没有回收子进程,释放子进程占用的资源,此时子进程将成为一个僵尸进程。
子进程变成僵尸进程,是因为父进程先执行完,没有替子进程收尸。而wait()并不是用来收尸的,只是防止父进程先于子进程退出;如果父进程先退出,会使子进程成为僵尸进程,这时候子进程的收尸就由1号init进程来回收。
主进程通过调用os.wait()等待子进程结束:
# -*-coding:utf-8-*- import os import time p = os.fork() if p == 0: time.sleep(10) print('执行子进程, pid={} ppid={} p={}'.format(os.getpid(), os.getppid(), p)) else: time.sleep(5) print('执行主进程, pid={} ppid={} p={}'.format(os.getpid(), os.getppid(), p)) os.wait()
[root@192 ~]# python fork.py & # 后台执行python代码 ### 五秒前,查看进程信息:主进程为1751,子进程为1752 [1] 1751 [root@192 ~]# ps aux | grep fork.py root 1751 0.5 0.1 125432 4588 pts/0 s 21:29 0:00 python fork.py root 1752 0.0 0.0 125432 2748 pts/0 s 21:29 0:00 python fork.py root 1754 0.0 0.0 112704 980 pts/0 s+ 21:29 0:00 grep --color=auto fork.py [root@192 ~]# 执行主进程, pid=1751 ppid=1572 p=1752 (此为程序打印信息,说明主进程已执行到os.wait()) ### 五秒后,主程序打印了信息并调用了os.wait(),查看进程信息:主进程为1751,子进程为1752,主进程没有结束 [root@192 ~]# ps aux | grep fork.py root 1751 0.1 0.1 125436 4588 pts/0 s 21:29 0:00 python fork.py root 1752 0.0 0.0 125432 2748 pts/0 s 21:29 0:00 python fork.py root 1756 0.0 0.0 112704 980 pts/0 s+ 21:29 0:00 grep --color=auto fork.py [root@192 ~]# 执行子进程, pid=1752 ppid=1751 p=0 (此为程序打印信息,说明子进程已执行完。 *注意,这里ppid不是1) [1]+ done python fork.py ### 十秒后,子进程执行完毕,子进程结束,父进程随着子进程的结束而结束 [root@192 ~]# ps aux | grep fork.py root 1758 0.0 0.0 112704 980 pts/0 s+ 21:29 0:00 grep --color=auto fork.py
# -*-coding:utf-8-*- import os import time variable = [] p = os.fork() if p == 0: variable.append(1) print('子进程 variable_id={}'.format(id(variable))) print('子进程 variable={}'.format(variable)) else: time.sleep(1) # 睡一秒,让子进程先改变变量的值 print('主进程 variable_id={}'.format(id(variable))) print('主进程 variable={}'.format(variable)) os.wait()
[root@192 ~]# python fork.py 子进程 variable_id=140426199897224 子进程 variable=[1] 主进程 variable_id=140426199897224 主进程 variable=[]
参考链接:
如有意见或建议,一起交流;如有侵权,请告知删除。
如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复
Python爬虫:Request Payload和Form Data的简单区别说明
浅谈Python中threading join和setDaemon用法及区别说明
Python3-异步进程回调函数(callback())介绍
python继承threading.Thread实现有返回值的子类实例
Python中使用threading.Event协调线程的运行详解
网友评论