说起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()