首页 > 其他分享 >28.并发编制【五】管道与多线程

28.并发编制【五】管道与多线程

时间:2024-05-28 20:23:21浏览次数:14  
标签:pipe task name 28 --- 并发 线程 time 多线程

【一】管道

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

相关文章

  • 30.并发编制【七】
    【一】信号量(Semahpore)1)概念互斥锁:允许在同一时刻只能有一个线程或进程同资源进行修改信号量:允许指定数量的进程或线程对资源进行修改2)示例frommultiprocessingimportProcess,Semaphoreimporttimeimportrandomdefeg(sem,user):#对信号量加锁sem.acq......
  • 【代码之髓】研究编程语言的核心点——结构化编程、函数、异常、作用域、类型、容器、
    写在前面本文基于人民邮电出版社发行的西尾泰和先生所著《代码之髓》有一定读书笔记性质,算是精简版改写。目录写在前面如何深入高效地学习语言从比较中学习从历史中学习程序设计语言诞生史语法的诞生程序的流程控制if诞生以前whilefor函数为什么要有函数函数的返回......
  • 高并发多高才算高?
    高并发是指系统能够同时处理大量并发请求的能力。在现代互联网应用中,高并发是常见的挑战之一,尤其是在电商促销、金融交易、社交媒体和流媒体服务等场景中。那么,到底多高的并发量才算是高并发呢?本文将从多个角度进行探讨。高并发的衡量标准高并发的具体标准因应用场景而异,通常使......
  • python+threading,实现简单的接口并发测试
    #-*-coding:utf-8-*-importthreadingfromutilsimporthttpUtilbody={"claimId":10179599,"protocols":[{"protocolUrl":None,"protocolContent":"<spanclass='c_......
  • 【go从入门到精通】精通并发编程-使用atomic管理状态和同步的无锁技术
    了解原子计数器        在Go中,原子计数器是多个goroutine可以同时访问的共享变量。术语“原子”是指在计数器上执行的操作的不可分割的性质。在Go中,原子计数器允许多个goroutine安全地更改共享变量,而无需使用锁或任何其他显式同步,这可确保数据完整性并避免竞......
  • kafka多线程顺序消费
    一、单线程顺序消费为了避免有的小伙伴第一次接触顺序消费的概念,我还是先介绍一下顺序消费是个什么东西。双十一,大量的用户抢在0点下订单。为了用户的友好体验,我们把订单生成逻辑与支付逻辑包装成一个个的MQ消息发送到Kafka中,让kafka积压部分消息,防止瞬间的流量压垮服务。那么......
  • 2882. 删去重复的行
    2882.删去重复的行DataFramecustomers+-------------+--------+|ColumnName|Type|+-------------+--------+|customer_id|int||name|object||email|object|+-------------+--------+在DataFrame中基于email列存在一些重复行。编写一个......
  • 2024-05-28 英语学习纪要
    Recentyear,moreandmorechineseculturalproductshavecomeintoglobalmarketandgetincreasinglyfacinatedbycustomersabroad.WiththerapiddevelopmentofofChineseculturaltrade(对外文化贸易,真的不会翻译……),theamountofexportedChinesecultura......
  • LeetCode-2877. 从表中创建 DataFrame
    2877.从表中创建DataFrame编写一个解决方案,基于名为student_data的二维列表创建一个DataFrame。这个二维列表包含一些学生的ID和年龄信息。DataFrame应该有两列,student_id和age,并且与原始二维列表的顺序相同。返回结果格式如下示例所示。示例1:输入:student_data:[......
  • 2024-05-28 英语学习纪要
    Recentyear,moreandmorechineseculturalproductshavecomeintoglobalmarketandgetincreasinglyfacinatedbycustomersabroad.WiththerapiddevelopmentofofChineseculturaltrade(对外文化贸易,真的不会翻译……),theamountofexportedChinesecultura......