个人博客页面链接:
http://www.shihao.online/
(django搭建的个人博客,还在完善中)
linux下使用fork()创建子进程
Linux 操作系统提供了一个 fork() 函数用来创建子进程,这个函数很特殊,调用一次,返回两次,因为操作系统是将当前的进程(父进程)复制了一份(子进程),然后分别在父进程和子进程内返回。子进程永远返回0,而父进程返回子进程的 PID(大于0)。我们可以通过判断返回值是不是 0 来判断当前是在父进程还是子进程中执行。
在 Python 中同样提供了 fork() 函数,此函数位于 os 模块下。
import os
import time
ret = os.fork()
if ret == 0:
while True:
print("-------1--------")
time.sleep(1)
else:
while True:
print("-------2--------")
time.sleep(1)
输出结果为:
---------------
---------------
---------------
---------------
---------------
---------------
---------------
---------------
---------------
---------------
---------------
---------------
---------------
---------------
无限循环。。。。。。(注:子进程和父进程的执行顺序不确定,即1和2输出顺序不一定,由操作系统的调度算法确定)
注意:如果父进程结束,子进程也跟着结束
如程序:
import os
import time
ret = os.fork()
if ret == 0:
while True:
print("---1-----")
time.sleep(1)
else:
print("---2-----")
输出结果为:
--------
--------
使用Process创建子进程
linux下可以使用fork创建子进程,但windows下不支持fork函数,但可以使用Process创建子进程
注意:与fork不同的是,主进程会等待Process子进程完成后结束。
Process语法结构如下:
Process([group [, target [, name [, args [, kwargs]]]]])
target:表示这个进程实例所调用对象;
args:表示调用对象的位置参数元组;
kwargs:表示调用对象的关键字参数字典;
name:为当前进程实例的别名;
group:大多数情况下用不到;
Process类常用方法:
is_alive():判断进程实例是否还在执行;
join([timeout]):是否等待进程实例执行结束,或等待多少秒;
start():启动进程实例(创建子进程);
run():如果没有给定target参数,对这个对象调用start()方法时,就将执行对象中的run()方法;
terminate():不管任务是否完成,立即终止;
Process类常用属性:
name:当前进程实例别名,默认为Process-N,N为从1开始递增的整数;
pid:当前进程实例的PID值;
from multiprocessing import Process
import time
import random
def test():
for i in range(1,5):
print("---%d---"%i)
time.sleep(1)
p = Process(target=test)
p.start()
p.join()
print("---main----")
输出结果为:
------
------
------
------
-------
进程池创建子进程
当需要创建的子进程数量不多时,可以直接利用multiprocessing中的Process动态成生多个进程,但如果是上百甚至上千个目标,手动的去创建进程的工作量巨大,此时就可以用到multiprocessing模块提供的Pool方法。
初始化Pool时,可以指定一个最大进程数,当有新的请求提交到Pool中时,如果池还没有满,那么就会创建一个新的进程用来执行该请求;但如果池中的进程数已经达到指定的最大值,那么该请求就会等待,直到池中有进程结束,才会创建新的进程来执行.
multiprocessing.Pool常用函数解析:
apply_async(func[, args[, kwds]]) :使用非阻塞方式调用func(并行执行,堵塞方式必须等待上一个进程退出才能执行下一个进程),args为传递给func的参数列表,kwds为传递给func的关键字参数列表;
apply(func[, args[, kwds]]):使用阻塞方式调用func
close():关闭Pool,使其不再接受新的任务;
terminate():不管任务是否完成,立即终止;
join():主进程阻塞,等待子进程的退出, 必须在close或terminate之后使用;
程序(非阻塞方式):
from multiprocessing import Pool
import os
import time
def worker(num):
for i in range(2):
print("===pid=%d===num=%d"%(os.getpid(), num))
time.sleep(1)
pool = Pool(3)
for i in range(5):
print("---%d---"%i)
pool.apply_async(worker, [i,])
print("---start----")
pool.close()
pool.join()
print("---end----")
---0---
---1---
---2---
---3---
---4---
---start----
===pid=24958===num=0
===pid=24959===num=1
===pid=24960===num=2
===pid=24958===num=0
===pid=24960===num=2
===pid=24959===num=1
===pid=24960===num=3
===pid=24958===num=4
===pid=24960===num=3
===pid=24958===num=4
---end----
程序(阻塞方式):
from multiprocessing import Pool
import os
import time
def worker(num):
for i in range(2):
print("===pid=%d===num=%d"%(os.getpid(), num))
time.sleep(1)
pool = Pool(3)
for i in range(5):
print("---%d---"%i)
pool.apply(worker, [i,])
print("---start----")
pool.close()
pool.join()
print("---end----")
---0---
===pid=24999===num=0
===pid=24999===num=0
---1---
===pid=25000===num=1
===pid=25000===num=1
---2---
===pid=25001===num=2
===pid=25001===num=2
---3---
===pid=24999===num=3
===pid=24999===num=3
---4---
===pid=25000===num=4
===pid=25000===num=4
---start----
---end----
注意:进程池和fork()一样,不会等待子程序结束
from multiprocessing import Pool
import os
import time
def worker():
for i in range(2):
print("===pid=%d==="%os.getpid())
time.sleep(1)
pool = Pool(3)
for i in range(5):
print("---%d---"%i)
pool.apply_async(worker)
------
------
------
------
------
fork()函数用于从已存在的进程中创建一个新进程。新进程称为子进程,而园进程称为父进程。使用fork()函数得到的子进程是父进程的一个复制品,它从父进程处继承了整个进程的地址空间,包括进程的上下文、代码段、进程堆栈、内存信息、打开的文件描述符、符号控制设定、进程优先级、进程组号、当前工作目录、根目录、资源限制和控制终端等,而子进程所独有的只有它的进程号、资源使用和计时器等。
因为子进程几乎是父进程的完全复制,所以父子两进程会运行同一个程序。这就需要用一种方式来区分它们,并使它们照此运行,否则,这两个进程不可能做不同的事。实际上是在父进程中执行fork()函数时,父进程会复制一个子进程,而且父
要让Python程序实现多进程(multiprocessing),我们先了解操作系统的相关知识。
Unix/Linux操作系统提供了一个fork()系统调用,它非常特殊。普通的函数调用,调用一次,返回一次,但是fork()调用一次,返回两次,因为操作系统自动把当前进程(称为父进程)复制了一份(称为子进程),然后,分别在父进程和子进程内返回。
子进程永远返回0,而父进程返回子进程的ID。这样做的...
开启多进程的几种方法
1. 使用多个进程启动多个Tornado实例
2. 使用tornado.process.fork_processes()方法启动多个进程
3.使用标准库中的multiprocessing
4.使用第三方模块gevent
5.使用官方提供方式
6.使用supervisor
以下各种方式仅供参考,本人亲测只有官方提供的方式比较靠谱。
1. 使用多个进程启动多个Tornado实例
fork()系统调用是Unix下以自身进程创建子进程的系统调用,
一次调用,两次返回,如果返回是0,
则是子进程,如果返回值>0,则是父进程(返回值是子进程的pid)
source = 10
i = 0
print '***********************'
pid = os.fork()
#这里会返回两次,所以下面的省略号会输出2次
print '......'
pid=os.fork()
1.只用在Unix系统中有效,Windows系统中无效
2.fork函数调用一次,返回两次:在父进程中返回值为子进程id,在子进程中返回值为0
import os
pid=os.fork()
if pid==0:
print(执行子进程,子进程pid={pid},父进程ppid={ppid}.format(pid=os.getpid(),ppid=os.getppid()))
else:
print(执行父进程,子进程pid={pid},父进程ppid
该函数创建子进程具体fork的过程:
(1)调用该函数即创建一个子进程,创建成功父进程返回子进程的pid,子进程返回0;
(2)创建子进程实际上对父进程的一个拷贝,共享代码空间,拷贝父进程的数据,也就是说父进程改变父进程的数据,子进程改变子进程的数据变量等;
二、示例代码分析
代码示例:
$curr_pid = posix_getpid();//获取当前的进程id
//将当前进程的id写入文件中
echo '当前进程:'.$cu
celery在容器运行,总是突然暴毙,查看日志发现如下错误:
Process 'ForkPoolWorker-170' pid:181 exited with 'signal 9 (SIGKILL)
解决办法:
由于celery在容器里面运行, 只分配了了一核, 导致的错误, 将配置升高核数, 问题解决
问题描述celery的worker端报错:-------------- worker2@zheng-VirtualBox v4.2.0 (windowlicker)---- **** ----- --- * *** * -- Linux-4.15.0-20-generic-x86_64-with-Ubuntu-18.04-bionic 2018-07-02 10:13:33-- * - ****...
1.os.fork():主进程执行完退出,不会等待子进程。子进程不会随着主进程结束,继续运行。
2.Process():主进程会等待子进程结束后,在结束整个程序。
3.Pool():主进程不会等待子进程,主进程结束后,整个程序都结束。可创建多个进程。
例:fork
import os,time
num = 0
pid = os.fork()
if pid == 0:
time.sl
1 进程的基本概念
什么是进程?
进程就是一个程序在一个数据集上的一次动态执行过程。进程一般由程序、数据集、进程控制块三部分组成。我们编写的程序用来描述进程要完成哪些功能以及如何完成;数据集则是程序在执行过程中所需要使用的资源;进程控制块用来记录进程的外部特征,描述进程的执行变化过程,系统可以利用它来控制和管理进程,它是系统感知进程存在的唯一标志。
进程的过程: 创建, 就绪, 运行 ,阻塞, ...
flask + celery
此报错是因为celery任务超过了 hard_time_limit 时间被celery主进程kill掉了, 应该还能找到此报错: MainProcess Hard time limit (300s) exceeded for (此处设置的hard_time_limit为300s)
把soft_time_limit设置少于hard_time_limit, 并进行异常捕获处理即可
查到公司原代码hard_time_limit为300s soft_time
windows上不支持,mac,linux,unix上可以
import os
pid = os.fork() # 操作系统自动把父进程的信息资源复制给了子进程,在两个进程中分别返回,父进程返回子进程的ID
if pid < 0:
print('fork失败')
elif pid == 0: # 子进程的pid为 0
print('我是子进程',os.getpid(),'我的父进程',os.getppid()) # os.getpid()获取当前进
fork()
python中的os模块封装了常见的系统调用,其中fork可以轻松的创建子进程
注意:fork只能在unix,linux,mac上运行,windows不能运行
import os
ret = os.fork() #创建子进程,函数返回一个值,子进程中这个值一定为0,父进程得到的是子进程的pid号
if ret == 0:
while True:
prin...
文章目录1.模块1.2.Process类1.3参数:1.4属性介绍1.5绑定方法2.开启子进程的两种方式2.1方式12.2方式23.进程数据隔离4.方法及属性4.1 .join()方法4.2 进程状态4.3进程名称与PID4.4守护进程5.进程同步与互斥锁5.1 抢票模拟6.队列6.1队列方法6.2生产消费模型7.信号量8.Event时间
Python中的多线程无法利用多核优势,可以通过去他的模块去实现(不常用)。
Python中大部分情况下需要使用多进程,内置multiprocessing模块,