python进程和线程

丶灬走出姿态 提交于 2019-12-05 19:00:32

1.多进程

针对unix/linux操作系统会提供一个fork()系统调用,其调用一次,返回两次,因为操作系统自动把当前文件复制了一份,称为父进程和子进程

子进程永远返回0,而父进程返回子进程的ID,这样一个父进程可以fork出很多子进程,so父进程要记下每个子进程的ID,而子进程通过调用getppid()拿到父进程的ID

python中的os模块封装了常见的系统调用,其中包括fork

1)Mutiprocessing

跨平台版本的多进程模块,提供process类来代表一个进程对象

from multiprocessing import Process
import os
#子进程要执行的代码
def run_proc(name):
    print("run child process %s(%s)..."%(name,os.getpgid()))
if _name_== '_main_':
    print(("parent process %s"%os.getpgid()))
    p = Process(target=run_proc,args=("test",))
    print("child process will start")
    p.start()
    p.join()
    print("child will end")

2)pool

如果启动大量的子进程,可以用进程池的方式批量创建子进程

from multiprocessing import Process
import os,time,random
#子进程要执行的代码
def long_time_task(name):
    print("run child process %s(%s)..."%(name,os.getpgid()))
    start=time.time()
    time.sleep(random.random()*3)
    end=time.time()
    print("Task %s runs %0.2f seconds"%(name,(end-start)))
if _name_=='_main_':
    print(("parent process %s"%os.getpgid()))
    p = pool(4)
    for i in range(5):
        p.apply_async(long_time_task,args=(i,))
    print("waiting for all subprocesses done")
    p.start()
    p.join()
    print("All subprocesses done")'

3)子进程

subprocess模块可以方便的启动一个子进程

import subprocess
print("$ nslookup www.python.org")
r = subprocess.call(["nslookup","www.python.org"])
print("Exit code",r)

如果子进程还需要输入,则可以通过communicate()方法输入

import subprocess
print("$ nslookup")
p = subprocess.Popen(["nslookup"],stdin = subprocess.PIPE,stdout = subprocess.PIPE,stderr = subprocess.PIPE)
output,err = p.communicate(b'set q=mx\npython.org\nexit\n')
print(output.decode("utf-8"))
print("Exit code",p.returncode)

4)进程间通信

process之间需要通信,python的multiprocessing模块包装了底层的机制,提供了Queue\Pipes等多种方式来交换数据

以Queue为例,一个往Queue里面写入数据,一个从Queue里面读数据

def read(q):
    print("process to read:%s"%os.getpgid())
    while True:
        value = q.get(True)
        print("get %s from queue"%value)
if _name_ = "main_":
    q =Queue()
    pw =Process(target = write,args=(q,))
    pr = Process(target=read,args=(q,))
    pw.start()
    pr.start()
    pw.join()
    pr.terminate()

2.多线程

python提供了连个模块,一个是_thread和threading,前者是低级模块,后者是高级模块,高级模块对低级模块进行了封装,绝大多数我们使用高级模块

import time,threading
def loop():
    print("thread in running"%threading.current_thread().name)
    n = 0
    while n < 5:
        n = n+1
        print("thread %s >>> %s"%threading.current_thread().name,n)
        time.sleep(1)
    print("thread %s  ended"%threading.current_thread().name)
print("thread %s is runing"%threading.current_thread().name)
t = threading.Thread(target=loop,name = "Looptaread")
t.start()
t.join()
print("thread %s  ended"%threading.current_thread().name)

1)lock

多线程和多进程的最大区别在于,多进程中每一个变量都有各自的备份,备份在每一个进程中,互不影响,而在多线程中,所有变量由所有线程共享,线程之间共享的问题在于多个线程同时更改一个变量,我们用锁实现,即threading_lock

import threading
balance = 0
lock = threading.Lock()
def run_thread(n):
    for i in range(1000):
        #先获取锁
    lock.acquire()
    try:
        change_it(n)
    finally:
        #释放锁
        lock.release()

 

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!