生产者消费者模型 开启线程的两种方式 多线程与多进程开启速度区别 线程进程pid 统一进程内线程是共享数据的 线程的其他方法 join与守护线程 互斥锁

生产者消费者模型

进程:

​ 生产者消费者模型

​ 编程思想, 模型, 设计模式, 理论等等, 都是交给你一种编程的方法, 以后遇到类似的情况, 套用即可

生产者消费者模型三要素

​ 生产者: 产生数据的

​ 消费者: 接收数据做进一步处理的

​ 容器: 盆(队列)

队列容器的作用

​ 起到缓冲的作用, 平衡生产力与消费力, 解耦

实例

import time
import random
from multiprocessing import Process, Queue


def producer(q, name):
    for i in range(1, 6):
        time.sleep(random.randint(1, 2))
        res = f"{i}号包子"
        q.put(res)
        print(f"生产者{name} 生产了{res}")


def consumer(q, name):
    while 1:
        try:
            food = q.get(timeout=3)
            time.sleep(random.randint(1, 3))
            print(f"33[31;0m 消费者{name} 吃了{food} 33[0m")
        except Exception:
            return


if __name__ == '__main__':
    q = Queue()

    p1 = Process(target=producer, args=(q, "孙宇"))
    p2 = Process(target=consumer, args=(q, "海狗"))

    p1.start()
    p2.start()

"""
生产者孙宇 生产了1号包子
生产者孙宇 生产了2号包子
 消费者海狗 吃了1号包子 
生产者孙宇 生产了3号包子
 消费者海狗 吃了2号包子 
生产者孙宇 生产了4号包子
生产者孙宇 生产了5号包子
 消费者海狗 吃了3号包子 
 消费者海狗 吃了4号包子 
 消费者海狗 吃了5号包子 
"""

开启线程的两种方式

进程是资源单位, 线程是执行单位

什么是线程

​ 一条流水线的工作流程.

进程:

​ 在内存中开启一个进程空间, 然后将主进程的所有的资源数据复制一份, 然后调用CPU去执行这些代码

具体描述进程:

​ 在内存中开启一个进程空间, 然后将主进程的所有的资源数据复制一份, 然后调用线程去执行代码

执行流程

​ 主线程子线程没有地位之分, 但是一个主线程在执行, 执行完, 要等待其他非守护子线程执行完之后, 才能结束主线程, 结束本进程

# 第一种方式
from threading import Thread
import time


def task(name):
    print(f"{name} is running")
    time.sleep(1)
    print(f"{name} is gone")


if __name__ == '__main__':

    t1 = Thread(target=task, args=("海狗",))
    t1.start()
    print("===主线程")
    # 线程没有主次之分
"""
李业 is running
===主线程
李业 is gone
"""
    
# 第二种方式
from threading import Thread
import time

class MyThread(Thread):

    def __init__(self, name, l1, s1):
        super(MyThread, self).__init__()
        self.name = name
        self.l1 = l1
        self.s1 = s1

    def run(self):
        print(f"{self.name} is running")
        time.sleep(1)
        print(f"{self.name} is gone")


if __name__ == '__main__':
    t1 = MyThread("李业", [1,2,3], "180")
    t1.start()
    print("===主线程")
"""
李业 is running
===主线程
李业 is gone
"""

多线程与多进程开启速度区别

from multiprocessing import Process
import time


def work():
    print("hello")


if __name__ == '__main__':
    start_time = time.time()
    lst = []
    for i in range(10):
        t = Process(target=work)
        t.start()
        lst.append(t)
    for i in lst:
        i.join()
    print(time.time() - start_time)
"""
hello
hello
hello
hello
hello
hello
hello
hello
hello
hello
1.004307746887207
"""


# 多线程
from threading import Thread
import time


def task():
    print("hello")


if __name__ == '__main__':
    start_time = time.time()
    lst = []
    for i in range(10):
        t = Thread(target=task)
        t.start()
        lst.append(t)
    for i in lst:
        i.join()
    print(time.time() - start_time)
"""
hello
hello
hello
hello
hello
hello
hello
hello
hello
hello
0.0019998550415039062
"""

​ 开启进程的开销非常大, 比开启线程的开销大很多.

​ 开启线程的速度非常快, 要快几十倍到上百倍.

线程进程pid

# 进程pid
from multiprocessing import Process
import os

def task():
    print(f"子进程:{os.getpid()}")
    print(f"主进程:{os.getppid()}")

if __name__ == '__main__':
    p1 = Process(target=task)
    p2 = Process(target=task)
    p1.start()
    p2.start()
    print(f"==主:{os.getpid()}")
"""
==主:51060
子进程:51128
主进程:51060
子进程:42856
主进程:51060
"""

# 线程pid
from threading import Thread
import os

def task():
    print(os.getpid())

if __name__ == '__main__':
    t = Thread(target=task)
    t1 = Thread(target=task)
    t.start()
    t1.start()
    print(f"===主线程:{os.getpid()}")
"""
51768
51768
===主线程:51768
"""
# 多线程在同一个进程内, 所以pid都一样

同一进程内线程是共享数据的

​ 线程与线程之间可以共享数据, 进程与进程之间需要借助队列等方法实现通信

​ 同一进程内的资源数据对于这个进程内的多个线程来说是共享的

线程的应用

​ 并发: 一个CPU看起来像是同时执行多个任务

​ 单个进程开启三个线程, 并发的执行任务

​ 开启三个进程并发的执行任务

​ 文本编辑器:

​ 1.输入文字

​ 2.在屏幕上显示

​ 3.保存在磁盘中

​ 开启多线程就非常简单了:

​ 数据共享, 开销小, 速度快

from threading import Thread


x = 3

def task():
    global x
    x = 100


if __name__ == '__main__':
    t1 = Thread(target=task)
    t1.start()
    t1.join()
    print(f"===主线程{x}")
    
"""
===主线程100
"""

线程的其他方法

from threading import Thread, current_thread, enumerate, activeCount
import os
import time

x = 3
def task():
    time.sleep(1)
    print(666)


if __name__ == '__main__':
    t1 = Thread(target=task)
    t2 = Thread(target=task)
    t1.start()
    t2.start()
    print(t1.isAlive())    # 判断子线程是否存活
    print(t1.getName())	   # 获取子线程名字
    t1.setName("子进程-1")  # 修改子线程名字
    print(t1.name)          # 获取子线程的名字 ***
    print(current_thread())  # 获取当前线程的内容
    print(enumerate())      # 获取当前进程下的所有线程,以列表形式展示
    print(activeCount())   # 获取当前进程下的所有存活线程的数量
    print(os.getpid())  
    
"""
True
Thread-1
子进程-1
<_MainThread(MainThread, started 60668)>
[<_MainThread(MainThread, started 60668)>, <Thread(子进程-1, started 55172)>, <Thread(Thread-2, started 62068)>]
3
61048
666
666
"""

join 与 守护线程

守护线程, 等待非守护子线程以及主线程结束之后, 结束

from threading import Thread
import time

def say_hi(name):
    print("你滚")
    time.sleep(2)
    print(f"{name} say hello")

if __name__ == '__main__':
    t = Thread(target=say_hi, args=("egon",))
    # t.setDaemon(True)      # 必须在t.start()前设置, 两种方法都可以
    t.daemon = True
    t.start()
    print("主线程")        # 注意 线程的开启速度比进程要快的多
    
"""
你滚
主线程
"""
from threading import Thread
import time

def foo():
    print(123)  
    time.sleep(1)
    print("end123")  

def bar():
    print(456)  
    time.sleep(3)
    print("end456")  


t1=Thread(target=foo)
t2=Thread(target=bar)

t1.daemon=True
t1.start()
t2.start()
print("main-------")  

"""
123
456
main-------
end123
end456
"""

互斥锁

from threading import Thread
import time
import random
x = 100

def task():
    global x
    temp = x
    time.sleep(random.randint(1, 3))
    temp = temp - 1
    x = temp


if __name__ == '__main__':
    l1 = []
    for i in range(100):
        t = Thread(target=task)
        l1.append(t)
        t.start()

    for i in l1:
        i.join()
    print(f'主线程{x}')
"""
主线程99
"""
# 多个任务共抢一个数据, 为了保证数据的安全性, 要让其串行


from threading import Thread
from threading import Lock
import time
x = 100

def task(lock):

    lock.acquire()
    global x
    temp = x
    temp = temp - 1
    x = temp
    lock.release()


if __name__ == '__main__':
    mutex = Lock()
    l1 = []
    for i in range(100):
        t = Thread(target=task,args=(mutex,))
        l1.append(t)
        t.start()

    time.sleep(3)
    print(f'主线程{x}')
"""
主线程0
"""
原文地址:https://www.cnblogs.com/beichen123/p/11397807.html