【一】管道
1)介绍
from multiprocessing import Pipe
# 创建管道
left_pipe,right_pipe = Pipe()
# 返回管道两端的连接对象,需在产生Process对象之前产生管道
# 默认参数dumplex:默认管道是全双工的
# 若为False,left_pipe只能用于接收,right_pipe只能用于发送
2)主要方法
# 接收数据(一端关闭,另一端取数据)
left_pipe.close()
rght_pipe.recv()
rght_pipe.close()
# 发送数据
right_pipe.close()
left_pipe.send()
left_pipe.close()
3)示例
from multiprocessing import Pipe, Process
def producer(name, p_conn):
# 获取两个管道
left_pipe, right_pipe = p_conn
# 放数据(关一个,再通过另一个管道传输)
right_pipe.close()
for i in range(5):
i += 1
data = f'生产者{name}生产了第{i}个商品'
print(data)
left_pipe.send(data)
# 关闭管道
left_pipe.close()
def customer(name, p_conn):
# 获取两个管道
left_pipe, right_pipe = p_conn
# 取数据(关一个,再通过另一个管道取数据)
left_pipe.close()
while True:
data = right_pipe.recv()
print(f'{name}购买了---{data}')
if not data:
break
right_pipe.close()
if __name__ == '__main__':
# 创建管道对象
pipe = Pipe()
# 创建生产者和消费者
producer_1 = Process(target=producer, args=('PR_1', pipe))
producer_1.start()
customer_1 = Process(target=customer, args=('CU_1', pipe))
# 创建守护进程
customer_1.daemon = True
customer_1.start()
producer_1.join()
# 生产者PR_1生产了第1个商品
# 生产者PR_1生产了第2个商品
# 生产者PR_1生产了第3个商品
# 生产者PR_1生产了第4个商品
# 生产者PR_1生产了第5个商品
# CU_1购买了---生产者PR_1生产了第1个商品
# CU_1购买了---生产者PR_1生产了第2个商品
# CU_1购买了---生产者PR_1生产了第3个商品
# CU_1购买了---生产者PR_1生产了第4个商品
# CU_1购买了---生产者PR_1生产了第5个商品
【二】多线程理论
1)线程概念
- 在操作系统中,每一个进程都有一块内存空间地址
- 线程:在进程内部开设的处理程序的进程
- 操作系统 --> 运行一个程序叫进程 ---> 进程里面又开了一个进程为线程
- 进程只是用来把资源集中到一起,线程 才是cpu上的执行单位
- 多线程:就是在进程CPU处理多个任务的逻辑
1.小结
- 进程(资源单位)
- 就是车间
- 存储设备及资源,
- 线程(执行单位)
- 就是里面的流水线
- 负责对数据进行加工和处理
进程和线程都是抽象的概念
2)创建开销问题
- 进程的创建开销 >> 线程的创建开销
3)进程和线程之间的关系
-
进程与进程之间是竞争关系
-
线程与线程之间是协调关系
4)区别
-
线程共享创建它的进程的地址空间; 进程具有自己的地址空间。
-
线程可以直接访问其进程的数据段; 进程具有其父进程数据段的副本。
-
线程可以直接与其进程中的其他线程通信; 进程必须使用进程间通信与同级进程进行通信。
-
新线程很容易创建; 新进程需要复制父进程。
-
线程可以对同一进程的线程行使相当大的控制权。 进程只能控制子进程。
-
对主线程的更改(取消,优先级更改等)可能会影响该进程其他线程的行为; 对父进程的更改不会影响子进程。
5)线程优点
- 减少了资源的消耗
- 同一个进程下的多个线程资源共享
【三】多线程的两种操作
1)直接调用 Thread 方法
from threading import Thread
import time, random
def work(name):
time_sleep = random.randint(1, 5)
print(f'{name}将持续{time_sleep}S')
time.sleep(time_sleep)
print(f'{name}结束')
def thread_work():
task_list = []
for i in range(5):
task = Thread(target=work, args=(f'ST{i}',))
task.start()
task_list.append(task)
for task in task_list:
task.join()
if __name__ == '__main__':
print('---开始---')
start_time = time.time()
thread_work()
end_time = time.time()
print(f'---总耗时{end_time - start_time}---')
# ---开始---
# ST0将持续1S
# ST1将持续2S
# ST2将持续5S
# ST3将持续5S
# ST4将持续2S
# ST0结束
# ST1结束
# ST4结束
# ST3结束
# ST2结束
# ---总耗时5.0015106201171875---
2)继承Thread 父类
from threading import Thread
import time, random
class MyThread(Thread):
def __init__(self, name):
super().__init__()
self.name = name
def run(self):
time_sleep = random.randint(1, 5)
print(f'{self.name}将持续{time_sleep}S')
time.sleep(time_sleep)
print(f'{self.name}结束')
def thread_work():
task_list = []
for i in range(5):
task = MyThread(name=f'ST{i}')
task.start()
task_list.append(task)
for task in task_list:
task.join()
if __name__ == '__main__':
print('---开始---')
start_time = time.time()
thread_work()
end_time = time.time()
print(f'---总耗时{end_time - start_time}---')
# ---开始---
# ST0将持续1S
# ST1将持续2S
# ST2将持续3S
# ST3将持续5S
# ST4将持续4S
# ST0结束
# ST1结束
# ST2结束
# ST4结束
# ST3结束
# ---总耗时5.002225875854492---
【四】线程之间共享数据
from threading import Thread
from multiprocessing import Process
num = 0
def worker(name):
global num
print(f'{name}改前:{num}')
num += 10
print(f'{name}改后:{num}')
# 进程之间的数据共享
def main_process():
task_list = []
for i in range(3):
task = Process(target=worker, args=(f'ST{i}',))
task.start()
task_list.append(task)
for task in task_list:
task.join()
# 线程之间的数据共享
def main_thread():
task_list = []
for i in range(3):
task = Thread(target=worker, args=(f'ST{i}',))
task.start()
task_list.append(task)
for task in task_list:
task.join()
if __name__ == '__main__':
main_process()
# ST0改前:0
# ST0改后:10
# ST1改前:0
# ST1改后:10
# ST2改前:0
# ST2改后:10
main_thread()
# ST0改前:0
# ST0改后:10
# ST1改前:10
# ST1改后:20
# ST2改前:20
# ST2改后:30
标签:pipe,task,name,28,---,并发,线程,time,多线程
From: https://www.cnblogs.com/Mist-/p/18218774