高级编程:并发通信

目录

一:通信隔离

二:线程资源抢占 

三:队列

四:生产者与消费者模型

五:补充:cmd快捷方式


一:通信隔离

        定义:进程与进程之间全局变量不共享

  

import multiprocessing

num = 18
def func():
    global num
    num += 1
    print('inner',num)
    return num

if __name__ == '__main__':
    t1 = multiprocessing.Process(target=func)
    t1.start()
    t1.join()  #主进程等待子进程结束任务
    print('outer',num)

       


解决办法:设置公共空间(空间可以是字典,或者列表)

        1.创建一个公共服务进程

        2.  将数据存到公共空间里面去

        3. 外部主进程再从公共空间拿数据

代码如下:

import multiprocessing
import threading
num = 18
def func(list1):
    global num
    num += 1
    print('inner',num)
    list1.append(num)  #3.将数据添加到列表里面去
    return num

if __name__ == '__main__':
    mg = multiprocessing.Manager()  # 1.创建一个公共服务进程
    li = mg.list()  #2.开辟一个列表空间
    t1 = multiprocessing.Process(target=func,args=(li,))
    t1.start()
    t1.join()  #主进程等待子进程结束任务
    # print('outer',num)
    # 外部从 列表空间 里拿,就用遍历拿
    for i in li:
        print('ourer',i)
    # print('outer',num)

        在函数内部,想要声明全局变量的话,一定要用global声明全局变量。


二:线程资源抢占 

        解决办法:设置互斥锁

        互斥锁概念:对共享数据进行锁定,保证同一时刻只能有一个线程去操作

        互斥锁的作用:同一时刻只能有一个线程去操作共享数据,保证共享数据不会出现错误问题

        互斥锁使用方法: Threading 里面的Lock() 

           1. 创建锁  mutex = threading.Lock()

           2. 上锁   mutex.acquire()

           3. 释放锁 mutex.release()

        互斥锁的优缺点:

        优点

                1. 使用互斥锁的好处确保某段关键代码只能由一个线程从头到尾完整去执行

        缺点

                1.使用互斥锁会影响代码的执行效率,多任务改成了单任务执行

                2. 互斥锁如果没有使用好容易出现死锁的情况,

                   什么死锁:一直等待对方释放所的场景就是死锁

                   死锁的结果:会造成应用程序的停止响应,不能再处理其它任务了。

                   避免死锁:在合适的地方释放锁。注意:释放锁一定要在Return之前添加。用mutex.release() 释放锁

import threading
import time

    #根据下标在列表中取值,保证同一时刻只有一个线程取值
    #创建互斥锁 并赋值lock:
lock = threading.Lock()

def get_value(index):
    lock.acquire()   #上锁
    my_list = [2,3,4,5,6]
    # 判断下标释放越界
    if index >= len(my_list):
        print('下标越界',index)
        lock.release()        #释放锁一定要在return之间添加
        return
    # 根据下标取值
    value = my_list[index]
    print(value)
    time.sleep(0.3)
    lock.release()    #释放锁


if __name__ == '__main__':
    # 模拟大量线程去执行取值操作
    for i in range(10):
        # t1 = threading.Thread(target=get_value,kwargs={'index':i})  #用的字典传参
        t1 = threading.Thread(target=get_value,args=(i,))             #用的元祖传参
        t1.start()    #启动子线程

                   


        

三:队列

定义:可以当做一个容器,可以存放我们的数据。

遵循的原则为:先进先出

队列操作

        入队:put

        出队:get

        判断数据是否为空:empty

        判断数据是否为满:full

import queue  #导入队列方法

q = queue.Queue(3)  #创建队列。此时3:是指只能往这个队列里存放三个数据,再多的话存放不了
q.put('a')
q.put('b')
q.put('c')
print(q.get())    #遵循先进先出原则
print(q.get())
print(q.get())

# print(q.full())    #看队列里是否满,满则Ture,否则就是False
#  print(q.empt())   #看队列里是否空,空则Ture,否则就是False

四:生产者与消费者模型

        谁是消费者?我们就是消费者。

        消费什么?消费客户带来的需求。

代码实现:

import threading
import queue
import time
import random
import multiprocessing

# q = queue.Queue(4)
q = multiprocessing.Queue(4) # 进程队列

# 消费者模型
class Comsumer(multiprocessing.Process):
    def __init__(self, q):
        super().__init__()
        self.q = q  # 传入队列

    def run(self):
        # 消费者逻辑  不需要考虑生产者 只需要从队列中获取任务
        while True:
            res = self.q.get()
            print(f'消费者处理了数据{res},处理结果为{res * 10}')


# 生产者
class Prodeucer(multiprocessing.Process):
    def __init__(self, q):
        super().__init__()
        self.q = q  # 传入队列

    def run(self):
        # 生产者逻辑, 不需要考虑消费者 只需要向队列中提交任务
        while True:
            time.sleep(1)
            item = random.randint(1, 100)
            print(f'生产者提交了任务{item}')
            self.q.put(item)


if __name__ == '__main__':
    pr = Prodeucer(q)
    cu = Comsumer(q)
    pr.start()
    cu.start()

五:补充:cmd快捷方式

        5.1:cmd快捷方式

        1.此行想跟上一行输入一致的时候,点上下左右键的 上键

感谢大家支持,每天尽量更新。

花有重开日,人生没有再少年。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

杨某人...

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值