python:线程、进程的之间通信和同步

说起python的线程,大家最有可能去菜鸟教程和廖雪峰老师的网站上看,是不是只懂这些:

一.调用进程,进程池和调用线程

from multiprocess import Process,Pool

#开启一个进程
p = Process(target=run_proc,args=('test',))
#run_proc()需要进程执行的函数,args是run_proc需要传入的参数
p.start()#启动进程
p.jion()#加入进程队列,等待执行


#使用进程池,适用需要开启很多进程
p = Pool(4)
for i in range(5):
    p.apply_async(run_proc, args=(i,))##run_proc()同上
p.start()
p.join()
import threading
import time
#线程,重写线程类
class MyThread(threading.Thread):
    def __init__(self,arg):
        #继承父类的初始化方法
        super(MyThread,self).__init__()
        self.arg = arg
    def run(self):
        time.sleep(1)
        print(self.arg)
#线程,直接调用线程类
t = threading.Thread(group=None,name=None,target=action,args=(i,))
t.start()

接下来看点别的

二.进程之间的通信和线程的通信

 进程之间的通信,

Queue,和Pipe可以实现进程之间的直接通信,Manager可实现数据共享
'''
首先线程是数据共享,需要做的是lock
而不同进程之间是相互独立的(不共享,父进程和子进程也不),那么他们要如何进行通信?
两个进程之间是完全独立的内存空间
Queue,和Pipe可以实现进程之间的直接通信,Manager可实现数据共享

'''
from multiprocessing import Process,Queue,Pipe,Manager
import queue,os



def run(q):
    q.put('测试')

def f(conn):
    conn.send([42,None,'hello from child1'])
    conn.send([42,None,'hello from child2'])
    print('from parent',conn.recv())
    conn.close()

def f_manager(d,l):
    d[os.getpid()] = os.getpid()
    l.append(os.getpid())
    print(l)

if __name__ == '__main__':
    q_thread = queue.Queue()#基于线程的queue,会报错
    q_process = Queue()#进程的queue
    process = Process(target=run,args=(q_process,))
    process.start()
    print(q_process.get())
    process.join()


    '''
    父进程和子进程虽然不能互相通信,但是子进程能够获取父进程的数据
    流程如下:
    子进程生成是把父进程当作一个变量拿过来,其实就是拿到queue里面的q,
    然后子进程copy一份
    然后用pickle进行序列化,再反系列化给父进程
    故子进程能够访问父进程的数据
    '''



    parent_conn,chlid_conn = Pipe()
    #开启一个进程
    process_01 = Process(target=f,args=(chlid_conn,))
    process_01.start()
    #看父进程收到的消息
    print(parent_conn.recv())
    parent_conn.send('儿子可好')
    process_01.join()


    with Manager() as manager:
        d = manager.dict()
        l = manager.list(range(5))

        process_list = []
        for i in range(10):
            process = Process(target=f_manager,args=(d,l))
            process.start()
            process_list.append(process)
        for res in process_list:
            res.join()
        print(d)

线程之间的通信:set()

#最简单的线程通信机制之一,一个线程通知事件,其他线程等待事件,set()默认为false clear()重置为false
#他就是一个简化版的condotion,他没有锁,无法使线程进入同步阻塞状态
import threading
import time

event = threading.Event()

def test():
    #等待事件,进入阻塞状态
    print('%s wait for event...' % threading.currentThread().getName())
    event.wait()

    #收到事件后进行操作
    print('%s recv event.' % threading.currentThread().getName())

t1 = threading.Thread(target=test)
t2 = threading.Thread(target=test)
t1.start()
t2.start()

time.sleep(2)

#我要发送事件通知了
print('the message is coming')
event.set()

三:进程和线程同步

进程同部:Lock

from multiprocessing import Process,Lock


def f(l,i):
    l.acquire()
    print('hello,handsome',i)
    l.release()

def f2(i):
    print('hello,handsome2',i)


if __name__ == '__main__':
    lock = Lock()
    for i in range(10):#加锁,防止一行为打印完,就开始打印下一行
        Process(target=f,args=(lock,i)).start()

线程同部,condition,rlock

import threading
import time
#condition 它包含rlock的锁定池还包含一个等待池
product = None
con  = threading.Condition()

def produce():
    global product
#进入阻塞状态,和通知
    if con.acquire():
        while True:
            if product is None:
                print('produce')
                product = 'somethong'
                #通知消费者商品已经生产好了
                #唤醒消费者的进程
                con.notify()#从等待池挑选一个线程并通知,收到的线程会自动调用acquire尝试获得锁定
            #等待通知
            con.wait()#进入condition的等待池
            time.sleep(2)
def consum():
    global product
    if con.acquire():
        while True:
            if product is not None:
                print("consum")
                product = None

                #通知生产之商品没了,唤醒生产的进程
                con.notify()
            #等待通知
            con.wait()
            time.sleep(2)

produce_thread = threading.Thread(group=None,name=None,target=produce)
consum_thread = threading.Thread(target=consum)
produce_thread.start()
consum_thread.start()
import threading
import time

num = 0
def no_lock(arg):
    global num
    time.sleep(1)
    num +=1
    print(num)
for i in range(0,100):
    t = threading.Thread(group=None,name=None,target=no_lock,args=(i,))
    t.start()
print('no lock 线程 is over')

rlock = threading.RLock()
def is_lock(arg):
    #开启acquire方法后,线程将会一致处于阻塞状态
    #什么时候解开?释放锁定或者时间到了
    rlock.acquire()
    global num2
    num2 +=1
    time.sleep(1)
    print(num2)
    #释放锁定
    rlock.release()
for i in range(0,10):
    t = threading.Thread(group=None,name=None,target=is_lock,args=(i,))
    t.start()

猜你喜欢

转载自blog.csdn.net/huangmengfeng/article/details/88653884