首页 > 编程语言 > 详细

Python@进程-线程-协程

时间:2021-08-04 15:53:00      阅读:21      评论:0      收藏:0      [点我收藏+]

进程

进程是正在运行程序的实例,一个程序可以有多个进程。

pid=os.fork()

作用:拷贝一份父进程(代码段,堆栈段,数据段)的数据来创建一个子进程。
返回:父进程返回子进程进程号,子进程返回0。
特点:子进程父进程相互独立,不在共享任何数据。

#以下代码在Linux下执行,window下没有fork函数
import os

pid = os.fork()

if pid < 0:
    print ‘Fail to create process‘
elif pid == 0:
    print ‘I am child process (%s) and my parent is (%s).‘ % (os.getpid(), os.getppid()) #os.getpid()获得当前(子)进程号,os.getppid()获得父进程号
else:
    print ‘I (%s) just created a child process (%s).‘ % (os.getpid(), pid)

#结果
I (86645) just created a child process (86646).
I am child process (86646) and my parent is (86645).

下验证了子进程从pid=os.fork()之后开始执行


[root@VM-0-15-centos ~]# cat tt.py
import os

print(‘start fork...‘)
pid = os.fork()
print(‘fork finish..‘)


if pid < 0:
    print(‘create False.‘)
elif pid == 0:
    print(‘I am child_proc [%d]‘ % (os.getpid()))
else:
    print(‘I am father_proc [%d]‘ % (os.getpid()))




[root@VM-0-15-centos ~]#
[root@VM-0-15-centos ~]# python3 tt.py
start fork...
fork finish..
I am father_proc [25188]
fork finish..
I am child_proc [25189]
[root@VM-0-15-centos ~]#

多进程

p=Process(target=child_proc, args=(x,))

import os
from multiprocessing import Process

# 子进程要执行的代码
def child_proc(name):
    print ‘Run child process %s (%s)...‘ % (name, os.getpid())

if __name__ == ‘__main__‘:
    print ‘Parent process %s.‘ % os.getpid()
    p = Process(target=child_proc, args=(‘test‘,))
    print ‘Process will start.‘
    p.start()
    p.join() #阻塞所有其他进程(包括父进程)
    print ‘Process end.‘
#结果
Parent process 7170.
Process will start.
Run child process test (10075)...
Process end.

from multiprocessing import Process‘

multiprocessing与平台有关,同一段代码:

import random
import os
from multiprocessing import Process

num = random.randint(0, 100)

def show_num():
    print("pid:{}, num is {}".format(os.getpid(), num))

if __name__ == "__main__":
    print("pid:{}, num is {}".format(os.getpid(), num))
    p = Process(target=show_num) #创建新进程
    p.start()
    p.join()

windows

pid:6504, num is 25
pid:6880, num is 6

Linux

pid:11747, num is 13
pid:11748, num is 13

我们发现window下num结果竟然不一样???
个人理解:
windows没有fork(),就不能像Linux那样让子进程从被创建的哪段代码之后开始执行。

spawn/fork/forkserver

这是因为根据系统平台的不同multiprocessing提供了3种启动进程的方式

spawn

父进程会启动一个新的解释器,子进程只会继承run()所需的资源。 不必要的文件描述符和句柄(一种指针)不会被继承。 该方法和fork,forkserver相比,启动进程较慢。

可在Unix和Windows上使用。 Windows上的默认设置。

fork

父进程使用 os.fork() 来产生 Python 解释器分叉。 子进程在开始时实际上与父进程相同,并且会继承父进程的所有资源。 多线程的安全是有问题的。

只能在Unix上使用。Unix上的默认设置。

forkserver

程序启动并选择forkserver启动方法时,将启动一个服务器进程。 之后每当需要一个新进程时,父进程就会连接到服务器并请求它分叉一个新进程。 分叉服务器进程是单线程的,因此使用 os.fork() 是安全的。 没有不必要的资源被继承。

可在Unix平台上使用,并支持通过Unix管道传递文件描述符。

进程池

可以使用进程池来创建多个进程

p=Pool(n)

p.apply_async(chile_func, args=(a,))

from multiprocessing import Pool

def foo(x):
    print ‘Run task %s (pid:%s)...‘ % (x, os.getpid())
    time.sleep(2)
    print ‘Task %s result is: %s‘ % (x, x * x)

if __name__ == ‘__main__‘:
    print ‘Parent process %s.‘ % os.getpid()
    p = Pool(4)         # 设置进程数
    for i in range(5):
        p.apply_async(foo, args=(i,))    # 设置每个进程要执行的函数和参数
    print ‘Waiting for all subprocesses done...‘
    p.close() #关闭进程池
    p.join()  #等待所有子进程执行完毕
    print ‘All subprocesses done.‘

#结果
Parent process 7170.
Run task 1 (pid:10320)...
Run task 0 (pid:10319)...
Run task 3 (pid:10322)...
Run task 2 (pid:10321)...
Waiting for all subprocesses done...
Task 1 result is: 1
Task 0 result is: 0
Run task 4 (pid:10320)...
Task 3 result is: 9
Task 2 result is: 4
Task 4 result is: 16
All subprocesses done.

进程通信

q=Queue()

p1=Processing(func_1, args=(q,))/q.put(message)

p2=Processing(func_2, args=(q,))/q.get(message)

# -*- coding: utf-8 -*-

from multiprocessing import Process, Queue

# 向队列中写入数据
def write_task(q):
    try:
        n = 1
        while n < 5:
            print "write, %d" % n
            q.put(n)
            time.sleep(1)
            n += 1
    except BaseException:
        print "write_task error"
    finally:
        print "write_task end"

# 从队列读取数据
def read_task(q):
    try:
        n = 1
        while n < 5:
            print "read, %d" % q.get()
            time.sleep(1)
            n += 1
    except BaseException:
        print "read_task error"
    finally:
        print "read_task end"

if __name__ == "__main__":
    q = Queue()  # 父进程创建Queue,并传给各个子进程

    pw = Process(target=write_task, args=(q,))
    pr = Process(target=read_task, args=(q,))

    pw.start()   # 启动子进程 pw,写入
    pr.start()   # 启动子进程 pr,读取
    pw.join()    # 等待 pw 结束
    pr.join()    # 等待 pr 结束
    print "DONE"
	
	
	
#结果
write, 1
read, 1
write, 2
read, 2
write, 3
read, 3
write, 4
read, 4
write_task end
read_task end
DONE

线程

Python@进程-线程-协程

原文:https://www.cnblogs.com/hugboy/p/Process-Thread-Coroutine.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!