查看进程号
进程的属性:进程名(name),进程号(pid---->process id)
# 每一个进程都有属于它的唯一进程号,通过进程号就可以找到这个进程
from multiprocessing import Process
import os
def index():
print('index')
print('子进程1:', os.getpid()) # 子进程1: 25096
# 在子进程中查看主进程号
print("主进程2:", os.getppid()) # 主进程2: 13704
if __name__ == '__main__':
p = Process(target=index)
p.start()
p.join()
# 在主进程中查看子进程号
print("子进程2:", p.pid) # 子进程2: 25096
print("主进程:", os.getpid()) # 主进程: 13704
队列的使用
常见的数据结构:
链表、单链表、双链表、循环链表、栈、队列、树、二叉树、平衡二叉树、红黑树、b树、b+树、b-树、图等
队列:先进先出
获取一个队列:
内置类:Queue
from multiprocessing import Queue
if __name__ == '__main__':
# 实例化类得到一个对象队列
q = Queue(4)
# 向队列中存放数据
q.put("hello word")
q.put("hello word1")
q.put("hello word2")
q.put("hello word4")
# 取出数据
print(q.get())
print(q.get())
print(q.get())
print(q.get())
方法:
from multiprocessing import Queue
q = Queue() # 括号内可以放数字来限制队列的大小
q.put() # 放数据 当队列满了再放 阻塞
q.get() # 取数据 当队列空了再取 阻塞
q.full() # 判断队列是否满了
q.empty() # 判断队列是否空了
q.get_nowait() # 取数据的时候如果没有数据直接报错
q.get(timeout=5) # 取数据的时候如果没有数据等5s还没有则直接报错
q.put("hello word4", block=False) # 当队列满的时候,放不进去的时候,直接报错
进程之间得的数据隔离问题
from multiprocessing import Process
from multiprocessing import Queue
def index(q):
a = 1
q.put("这是子进程的数据1234")
q.put(a)
"""
我在子进程中放入一个数据,然后在主进程中取出这个数据,如果能去得到,就说明通信了,如果取不到就说明不通信
"""
if __name__ == '__main__':
q = Queue(3)
p = Process(target=index, args=(q,))
p.start()
# 在主进程中取子进程写进去的数据
print(q.get()) # 这是子进程的数据1234
print(q.get()) # 1
"""现在队列中的数据在哪里存着? 在内存中存着,当数据量很大的时候,很占用我们机器的内存"""
# 以后我们可能会使用专业的消息队列: kafka、rabbitmq、rocketmq等专业的消息队列
"""当前使用较多的消息队列有:RabbitMQ、RocketMQ、ActiveMQ、Kafka、ZeroMQ、MetaMq等"""
生产者消费者模型
# 单生产、单消费
from multiprocessing import Process, Queue
def producer(q):
for i in range(10):
q.put(f"这是第{i}个包子")
def consumer(q):
while True:
res = q.get()
if res is None:
break
print(res)
if __name__ == '__main__':
q = Queue(20)
# 开启一个生产者的线程
p = Process(target=producer, args=(q,))
p.start()
# 开启一个消费者的线程
p1 = Process(target=consumer, args=(q,))
p1.start()
p.join()
q.put(None)
# 多生产者、少消费者
from multiprocessing import Process, Queue
import time
def producer(q, name, food):
for i in range(10):
q.put(f"这是{name}的第{i}个{food}")
time.sleep(0.1)
def consumer(q):
while True:
res = q.get()
if res is None:
break
print(res)
if __name__ == '__main__':
q = Queue(20)
# 开启一个生产者的线程
p = Process(target=producer, args=(q, "kevin", "面包"))
p.start()
p1 = Process(target=producer, args=(q, "tom", "油条"))
p1.start()
p2 = Process(target=producer, args=(q, "jack", "水果"))
p2.start()
p5 = Process(target=producer, args=(q, "tank", "橙子"))
p5.start()
# 开启一个消费者的线程
p3 = Process(target=consumer, args=(q,))
p3.start()
p4 = Process(target=consumer, args=(q,))
p4.start()
p.join()
p1.join()
p2.join()
p5.join()
q.put(None)
q.put(None)
# 少生产者,多消费者的情况
from multiprocessing import Process, Queue
def producer(q, name, food):
for i in range(10):
q.put(f"这是{name}的第{i}个{food}")
def consumer(q):
while True:
res = q.get()
if res is None:
break
print(res)
if __name__ == '__main__':
q = Queue(20)
# 开启一个生产者的线程
p = Process(target=producer, args=(q, "kevin", "面包"))
p.start()
p1 = Process(target=producer, args=(q, "tom", "油条"))
p1.start()
# 开启一个消费者的线程
p2 = Process(target=consumer, args=(q,))
p2.start()
p3 = Process(target=consumer, args=(q,))
p3.start()
p4 = Process(target=consumer, args=(q,))
p4.start()
p5 = Process(target=consumer, args=(q,))
p5.start()
p.join()
p1.join()
q.put(None)
q.put(None)
q.put(None)
q.put(None)
线程理论
什么是线程?
"""
进程:资源单位
线程:执行单位
如果将进程比喻做一个电子厂,那么线程就是一条条的流水线
每一个进程都会自带一条线程,而这条线程就是主线程
进程:资源单位(起一个进程仅仅代表在内存空间中开辟出来一块独立的空间而已)
线程:执行单位(真正被CPU执行的其实是进程里面的线程,线程指的就是代码的执行过程,执行代码中所需要使用到的资源都找所在的进程索要)
进程和线程都是虚拟单位,只是为了我们更加方便的描述问题
"""
为何要有线程?
"""
开设进程
1.申请内存空间 耗资源
2.“拷贝代码” 耗资源
开线程
一个进程内可以开设多个线程,在用一个进程内开设多个线程无需再次申请内存空间操作
总结:
开设线程的开销要远远的小于进程的开销
同一个进程下的多个线程数据是共享的!!!
"""
开启线程
from threading import Thread
def index():
print("这是子线程")
"""
target=None, name=None,
rgs=(),
kwargs=None,
daemon=None,
name='': 修改线程名称
"""
if __name__ == '__main__':
t = Thread(target=index)
t.start()
# 在子进程里面开启一个子线程
from multiprocessing import Process
from threading import Thread
def child_thread():
print("这是子线程")
def child_process():
print("这是子进程")
t = Thread(target=child_thread)
t.start()
if __name__ == '__main__':
p = Process(target=child_process)
p.start()
"""
执行结果:
这是子进程
这是子线程
"""
开启多线程
from threading import Thread
def child_thread(i):
print(f"这是子线程{i}")
if __name__ == '__main__':
t_list = []
for i in range(5):
t = Thread(target=child_thread, args=(i,))
t.start()
t_list.append(t)
for j in t_list:
j.join()
"""
执行结果:
这是子线程0
这是子线程1
这是子线程2
这是子线程3
这是子线程4
"""