进程锁
将并行变成了串行,提高了安全性,降低了效率
# 由并发变成了串行,牺牲了运行效率,但避免了竞争
import os
import time
import random
from multiprocessing import Process,Lock
def work(lock,n):
lock.acquire()
print('%s: %s is running' % (n, os.getpid()))
time.sleep(random.random())
print('%s: %s is done' % (n, os.getpid()))
lock.release()
if __name__ == '__main__':
lock=Lock()
for i in range(3):
p=Process(target=work,args=(lock,i))
p.start()
进程之间的数据隔离问题
n=100
def task():
global n
n=1
print("子进程")
from multiprocessing import Process
if __name__ == '__main__':
p = Process(target=task)
p.start()
p.join()
print("主进程中的值:", n)
查看进程号
def task():
print('task进程的进程号:',os.getpid())
print('task进程的父进程的进程号:',os.getpid())
if __name__ == '__main__':
p = Process(target=task,)
p.start()
print('子进程的进程号:',p.pid)
print('主进程的进程号:',os.getpid())
队列
队列属于数据结构的一种,先进先出
数据结构:链表、单链表、双链表、循环链表、栈、队列、树、二叉树、图
from multiprcocessing import Queue
q=Queue(10)#maxsize是队列中允许的最大项数。如果省略此参数,则无大小限制。
q.put(111)
print(q.get())
#如果往队列里面放数据放不进去的时候,会立马报错,报队列已满的错误信息
q.get_nowait()不等待立刻报错
q.empty()如果调用此方法时 q为空,返回True
q.full()如果q已满,返回为True
生产者消费者模型
在并发编程中使用生产者和消费者模式能够解决绝大多数并发问题。该模式通过平衡生产线程和消费线程的工作能力来提高程序的整体处理数据的速度。
在线程世界里,生产者就是生产数据的线程,消费者就是消费数据的线程。在多线程开发当中,如果生产者处理速度很快,而消费者处理速度很慢,那么生产者就必须等待消费者处理完,才能继续生产数据。同样的道理,如果消费者的处理能力大于生产者,那么消费者就必须等待生产者。为了解决这个问题于是引入了生产者和消费者模式。
生产者消费者模式是通过一个容器来解决生产者和消费者的强耦合问题。生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消费者处理,直接扔给阻塞队列,消费者不找生产者要数据,而是直接从阻塞队列里取,阻塞队列就相当于一个缓冲区,平衡了生产者和消费者的处理能力。
from multiprocessing import Process,Queue
import time,random,os
def consumer(q):
while True:
res=q.get()
time.sleep(random.randint(1,3))
print('%s 吃 %s' %(os.getpid(),res))
def producer(q):
for i in range(10):
time.sleep(random.randint(1,3))
res='包子%s' %i
q.put(res)
print('生产了 %s' %(os.getpid(),res))
if __name__ == '__main__':
q=Queue()
#生产者们:即厨师们
p1=Process(target=producer,args=(q,))
#消费者们:即吃货们
c1=Process(target=consumer,args=(q,))
#开始
p1.start()
c1.start()
print('主')
线程理论
在一个进程中,线程就是必须存在的,至少要有一个线程来执行任务。一个进程中可以有多个线程,在一个进程中可有开启多个线程来执行任务。进程和线程都是有操作系统调度的。
进程是操作系统分配资源的基本单位,线程是操作系统执行的最小单位
守护线程(进程)
无论是进程还是线程,都遵循:守护xx会等待主xx运行完毕后被销毁。需要强调的是:运行完毕并非终止运行。
from threading import Thread
import time
def task(name):
time.sleep(2)
print('%s say hello' %name)
if __name__ == '__main__':
t=Thread(target=task,args=('aa',))
t.setDaemon(True) #必须在t.start()之前设置
t.start()
print('主线程')
print(t.is_alive())