网络编程,线程,进程"补充"
1,进程间的通信IPC
如何时间进程之间通信
队列:先进先出
堆栈:先进后出
利用队列时间进程之间通信
1,如何创建一个队列:如
from multiprocessing import Queue
#full判断这个队列里面的值是否是满的,返回值是布尔值
#put,往队列添加值
#get,从队列中取值
q = Queue(5)#产生一个能存放最大数据的五个队列
q.put(1)
q.put(2)
q.put(3)
q.put(3)
q.put(3)
print(q.full())
print(q.get())
print(q.get())
print(q.get())
print(q.get())#如果队列中没有值了那么进程不会结束而是在等在哪里
from multiprocessing import Queue
q = Queue(5)
for i in range(5):#for 循环往队列里面存放数据
q.put(i)
print(q.get())
print(q.get())
print(q.get())
q.get_nowait()#在队列有数据的情况下,和get取值是一样的但是当这个队列没有数据了 那么直接报错
print(q.empty())#判断队列是否为空,需要注意的是在并发的时候这个判断的不是很准确,因为在并发的时候可能在有一瞬间队列是没有值的
2,进程间通信IPC机制
from multiprocessing import Process ,Queue
def producer(q):
q.put("hello SB")
def consumer(q):
print(q.get())
if __name__ == '__main__':
q = Queue()#创建 一个队列
p = Process(target=producer,args=(q,))#将创建好的队列当参数传过去
c = Process(target=consumer,args=(q,))
p.start()
c.start()
"""创建两个子进程,一个存 一个取
"""
2,生产者消费模型
生产者模型
生产者:做包子 生产数据的
消费者:买包子 处理数据的
生产数据多,处理出数据 系统会卡
生产数据少,处理数据多,处理会等待
解决供需不平衡的问题
定义一个队列。用来存放固定数量的数据
生产数据放在队列,处理数据从队列中取
解决一个生产者和消费者不需要直接打交道,两者都通过队列打交道
Queue:管道+一个锁 相当于
JoinableQueue:可以被等待的管道,
from multiprocessing import Process ,Queue,JoinableQueue
import random
import time
def producer(name,shangpin,q):
for i in range(5):
data = f"大厨{name}生产了{shangpin}{i}"
time.sleep(random.random())#随机时间
q.put(data)
print(data)
def consumer(name,q):
while True:
data = q.get()
if data==None:break
print(f"{name}吃了{data}")
time.sleep(random.random())
q.task_done()#告诉队列你已经从队列中取出一个数据并且处理完毕了
if __name__ == '__main__':
q = JoinableQueue()
p = Process(target=producer,args=("jason","包子",q,))
p1 = Process(target=producer, args=("tank","鲍鱼",q,))
s = Process(target=consumer,args=("egon",q))
s1 = Process(target=consumer, args=("女老师", q))
p.start()
p1.start()
s.daemon =True#设置守护进程
s1.daemon = True
s.start()
s1.start()
p.join()
p1.join()
q.join()#等待队列所有数据全部取出才能结束
1,线程理论
1,什么是线程
进程:资源单位
线程:执行单位
进程就是创建了一个内存空间,而线程是进程内存空间里面的代码
注意:每一个进程中都会自带一个线程
2,为什么要有线程
开一个进程:
申请内存空间 耗时
将代码拷贝到申请的内存空间中,耗时
开一个线程:
不需要申请内存空间
开线程的开销远远小于开进程的开销
3,如何是使用线程
开启线程的两种方式
2,创建线程的两种方式
from threading import Thread
import time
#第一种使用继承
class Mythread(Thread):
def __init__(self,name):
super().__init__()
self.name = name
def run(self):
print(f"{self.name}是个人才")
time.sleep(2)
print(f"{self.name}等待了")
if __name__ == '__main__':
t = Mythread("杨鑫")
t.start()
print("主")
from threading import Thread
import time
#第二种方式
def task(name):
print(f"{name}是个人才")
time.sleep(2)
print(f"{name}等待了")
if __name__ == '__main__':
t = Thread(target=task,args=("yangxin",))
t.start()
print("主")
3,线程对象及其他方法
from threading import Thread ,current_thread,active_count
import time
import os
def task(name):
print(f"{name}来了")
print("子程序",current_thread().name)#查询子线程
print("子程序",os.getpid())#查询子线程的pip号
time.sleep(2)
print("我被延迟了")
if __name__ == '__main__':
t = Thread(target=task,args=("haha",))
t1 = Thread(target=task,args=("yangxin",))
t.start()#开辟一个线程
t1.start()#开辟一个线程
t1.join()
print("查询当前正在活跃的子线程个数",active_count())
#小的代码执行完线程就开始了
print("主")
print("主线程",current_thread().name)
print("主线程",os.getpid())
4,守护线程
from threading import Thread ,current_thread
def task(i):
print(current_thread().name)
time.sleep(i)
print("GG")
if __name__ == '__main__':
t = Thread(target=task,args=(1,))
t.daemon = True#设置守护线程
t.start()
# t.join()#如果不加这个join那么主结束子线程中的GG也无法打印直接跟随着主进程死亡
print("主")
"""
主线程的结束也就意味着进程的结束
主线程必须等待其他非守护线程的结束才能结束
(意味子线程在运行的时候需要使用进程中的资源,而主线程一旦结束了资源也就销毁了)
5,线程之间通信
from threading import Thread
money = 666
def task():
global money
money = 999
t = Thread(target=task)
t.start()
t.join()
print(money)
6线程互斥锁
from threading import Thread,Lock
import time
n = 100
def task(mutex):
global n
mutex.acquire()
tmp = n
time.sleep(0.1)
n = tmp - 1
mutex.release()
t_list = []
mutex = Lock()
for i in range(100):
t = Thread(target=task,args=(mutex,))
t.start()
t_list.append(t)
for t in t_list:
t.join()
print(n)
练习
from threading import Thread
from multiprocessing import Process
import time
def foo():
print(123)
time.sleep(1)
print("end123")
def bar():
print(456)
time.sleep(3)
print("end456")
if __name__ == '__main__':
t1=Thread(target=foo)
t2=Thread(target=bar)
t1.daemon=True
t1.start()
t2.start()
print("main-------")