进程、线程补充与协程相关介绍

补充点

当你知道锁的使用必须释放锁时,实际上你在操作锁的时候极容易发生死锁(整个程序都被卡住和阻塞)。

[En]

When you know that the use of the lock must release the lock, in fact, you are extremely prone to deadlock when you operate the lock (the whole program is jammed and blocked).

from threading import Thread, Lock
import time

mutexA = Lock()
mutexB = Lock()
类只要加括号多次 产生的肯定是不同的对象
如果要实现多个圆括号,请等到相同的对象单例模式<details><summary>*<font color='gray'>[En]</font>*</summary>*<font color='gray'>If you want to implement multiple parentheses, wait until the same object singleton pattern</font>*</details>

class MyThead(Thread):
    def run(self):
        self.func1()
        self.func2()

    def func1(self):
        mutexA.acquire()
        print('%s 抢到A锁'% self.name)  # 获取当前线程名
        mutexB.acquire()
        print('%s 抢到B锁'% self.name)
        mutexB.release()
        mutexA.release()

    def func2(self):
        mutexB.acquire()
        print('%s 抢到B锁'% self.name)
        time.sleep(2)
        mutexA.acquire()
        print('%s 抢到A锁'% self.name)  # 获取当前线程名
        mutexA.release()
        mutexB.release()

if __name__ == '__main__':
    for i in range(10):
        t = MyThead()
        t.start()

递归锁的特点:

可以被连续的acquire和release
但锁只能被第一个执行上述操作的人抢走。

[En]

But the lock can only be grabbed by the first one to do the above.

它的内部有一个计数器 每acquire一次计数加一 每realse一次计数减一
只要计数不为0 那么其他人都无法抢到该锁

&#x4EE3;&#x7801;&#x53EA;&#x9700;&#x8981;&#x5C06;&#x4E0A;&#x8FF0;&#x6B7B;&#x9501;&#x7684;
mutexA = Lock()
mutexB = Lock()
&#x6362;&#x6210;
mutexA = mutexB = RLock()
&#x8FD9;&#x6837;&#x6B7B;&#x9501;&#x7684;&#x7A0B;&#x5E8F;&#x5C31;&#x53EF;&#x4EE5;&#x6B63;&#x5E38;&#x8FD0;&#x884C;&#x4E0B;&#x53BB;

信号量可能对应于不同阶段的不同技术点。在并发编程中,信号量指的是锁!

[En]

Semaphores may correspond to different technical points at different stages. In concurrent programming, semaphores refer to locks!

信号量和互斥量的比较:信号量可以看作多个坑,互斥量只能是一个坑!

[En]

Comparison between semaphores and mutexes: semaphores can be regarded as multiple pits, mutexes can only be one pit!

信号量的具体语法:

from threading import Thread, Semaphore  # &#x4FE1;&#x53F7;&#x91CF;&#x7684;&#x6A21;&#x5757;
import time,random

sm = Semaphore(5)  # &#x8868;&#x793A;&#x540C;&#x65F6;&#x5F00;&#x8BBE;5&#x4E2A;&#x5751;&#x4F4D;&#xFF08;&#x4E92;&#x65A5;&#x9501;&#x53EA;&#x5F00;&#x8BBE;&#x4E00;&#x4E2A;&#xFF09;

def task(name):
    sm.acquire()  # &#x52A0;&#x9501;
    print('%s&#x6B63;&#x5728;&#x8E72;&#x5751;'%name)
    time.sleep(random.randint(1,3))  # &#x8E72;&#x5751;&#x65F6;&#x95F4;&#x4E0D;&#x7B49;
    sm.release()  # &#x91CA;&#x653E;&#x9501;

if __name__ == '__main__':
    for i in range(20):  # 20&#x4E2A;&#x4EBA;&#x53BB;&#x62A2;5&#x4E2A;&#x5395;&#x6240;
        t = Thread(target=task,args=(i,))
        t.start()

主进程/线程等待子进程/线程运行结束时,我们使用的是join方法!

而需要子进程/线程之间的相互的等待结束,需要用到event事件

from threading import Thread,Event
import time

1.&#x5148;&#x4EA7;&#x751F;&#x4E00;&#x4E2A;event&#x5BF9;&#x8C61;
event = Event()

def person():
    print('&#x4F60;&#x6765;&#x4E86;')
    time.sleep(2)
    event.set()  # 2.&#x53D1;&#x9001;&#x4FE1;&#x53F7;&#xFF0C;&#x8868;&#x793A;&#x6211;&#x6267;&#x884C;&#x5B8C;&#x6BD5;&#x4E86;&#xFF0C;&#x4F60;&#x53EF;&#x4EE5;&#x7ED3;&#x675F;&#x4E86;

def my():
    event.wait()  # 3.&#x63A5;&#x6536;&#x5230;&#x4FE1;&#x53F7;&#xFF0C;&#x597D;&#x7684;&#x6211;&#x5F00;&#x59CB;&#x6267;&#x884C;
    print('&#x6211;&#x8D70;&#x4E86;')

if __name__ == '__main__':
    t = Thread(target=person)
    t1 = Thread(target=my)
    t1.start()
    t.start()

池是用来保证计算机硬件安全的情况下最大限度的利用计算机,它降低了程序运行的效率但是保证了计算机硬件的安全,从而让你的程序正常的运行!!

1.&#x5BFC;&#x5165;&#x8FDB;&#x7A0B;&#x6C60;/&#x7EBF;&#x7A0B;&#x6C60;&#x6A21;&#x5757;
from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor
import time

2.&#x521B;&#x5EFA;&#x4E00;&#x4E2A;&#x7EBF;&#x7A0B;&#x6C60;&#x5BF9;&#x8C61;&#xFF0C;&#x8BE5;&#x5BF9;&#x8C61;&#x62EC;&#x53F7;&#x5185;&#x4E0D;&#x4F20;&#x53C2;&#x6570;&#xFF0C;&#x9ED8;&#x8BA4;&#x662F;&#x5F00;&#x8BBE;&#x5F53;&#x524D;cpu&#x4E2A;&#x6570;*5&#x7684;&#x7EBF;&#x7A0B;
pool = ThreadPoolExecutor(5) # &#x4F20;&#x5165;&#x53C2;&#x6570;5&#xFF0C;&#x8868;&#x793A;&#x6C60;&#x5B50;&#x91CC;&#x56FA;&#x5B9A;&#x521B;&#x5EFA;&#x4E86;5&#x4E2A;&#x7EBF;&#x7A0B;&#xFF0C;&#x8FD9;5&#x4E2A;&#x7EBF;&#x7A0B;&#x4E0D;&#x4F1A;&#x91CD;&#x590D;&#x521B;&#x5EFA;&#x548C;&#x9500;&#x6BC1;

def task(name):
    print('%s&#x6765;&#x4E86;'% name)
    time.sleep(2)

3.&#x671D;&#x6C60;&#x5B50;&#x4E2D;&#x63D0;&#x4EA4;&#x4EFB;&#x52A1;&#xFF0C;&#x7B2C;&#x4E00;&#x4E2A;&#x53C2;&#x6570;&#x662F;&#x51FD;&#x6570;&#x540D;&#xFF0C;&#x7B2C;&#x4E8C;&#x4E2A;&#x53C2;&#x6570;&#x662F;&#x51FD;&#x6570;&#x9700;&#x8981;&#x4F20;&#x5165;&#x7684;&#x53C2;&#x6570;
"""
&#x540C;&#x6B65;&#x63D0;&#x4EA4;&#xFF1A;&#x63D0;&#x4EA4;&#x4EFB;&#x52A1;&#x4E4B;&#x540E;&#x539F;&#x5730;&#x7B49;&#x5F85;&#x8FD4;&#x56DE;&#x7ED3;&#x679C;&#xFF0C;&#x4E0D;&#x5F80;&#x4E0B;&#x6267;&#x884C;&#x4EFB;&#x52A1;
&#x5F02;&#x6B65;&#x63D0;&#x4EA4;&#xFF1A;&#x63D0;&#x4EA4;&#x4EFB;&#x52A1;&#x4E4B;&#x540E;&#x4E0D;&#x539F;&#x5730;&#x7B49;&#x5F85;&#x8FD4;&#x56DE;&#x7ED3;&#x679C;&#xFF0C;&#x7EE7;&#x7EED;&#x5F80;&#x4E0B;&#x6267;&#x884C;
"""
pool.submit(task,'zhang') # &#x6CE8;&#x610F;&#xFF1A;&#x8FD9;&#x91CC;&#x7684;&#x63D0;&#x4EA4;&#x662F;&#x4E00;&#x4E2A;&#x5F02;&#x6B65;&#x63D0;&#x4EA4;
print('&#x4E3B;')

&#x4F18;&#x5316;
list = []
for i in range(20): # &#x5411;&#x6C60;&#x5B50;&#x4E2D;&#x63D0;&#x4EA4;20&#x4E2A;&#x4EFB;&#x52A1;&#x3002;&#x6C60;&#x5B50;&#x4E2D;&#x53EA;&#x6709;5&#x4E2A;&#x7EBF;&#x7A0B;
    res = pool.submit(task,i)  # &#x6C60;&#x65B9;&#x6CD5;&#x5F02;&#x6B65;&#x63D0;&#x4EA4;&#x4E4B;&#x540E;&#x6709;&#x4E00;&#x4E2A;&#x8FD4;&#x56DE;&#x503C;&#xFF0C;&#x8BE5;&#x8FD4;&#x56DE;&#x503C;&#x662F;&#x4E00;&#x4E2A;future&#x5BF9;&#x8C61;
    # print(res.result())  # &#x8BE5;&#x5BF9;&#x8C61;&#x6709;&#x4E00;&#x4E2A;result&#x65B9;&#x6CD5;&#xFF0C;&#x53EF;&#x4EE5;&#x7528;&#x6765;&#x8FD4;&#x56DE;&#x5BF9;&#x5E94;&#x7EBF;&#x7A0B;&#x51FD;&#x6570;&#x7684;&#x8FD4;&#x56DE;&#x503C;&#xFF0C;&#x6CA1;&#x6709;&#x8FD4;&#x56DE;&#x503C;&#x5219;&#x8FD4;&#x56DE;none
    # result&#x65B9;&#x6CD5;&#x7684;&#x4F7F;&#x7528;&#x4F7F;&#x5F97;submi&#x5F02;&#x6B65;&#x63D0;&#x4EA4;&#x53D8;&#x6210;&#x4E86;&#x540C;&#x6B65;&#x63D0;&#x4EA4;
    list.append(res)
&#x5982;&#x679C;&#x60F3;&#x7B49;&#x5F85;&#x6240;&#x6709;&#x7684;&#x7EBF;&#x7A0B;&#x5168;&#x90E8;&#x6267;&#x884C;&#x5B8C;&#x6BD5;&#xFF0C;&#x5728;&#x5F80;&#x4E0B;&#x6267;&#x884C;&#x4EE3;&#x7801;&#xFF0C;&#x53EF;&#x4EE5;&#x4F7F;&#x7528;&#x6C60;&#x7684;shutdown&#x65B9;&#x6CD5;
pool.shutdown() # shutdown&#x7684;&#x4F5C;&#x7528;&#x662F;&#x7B49;&#x5F85;&#x6240;&#x6709;&#x7EBF;&#x7A0B;&#x6C60;&#x8FD0;&#x884C;&#x5B8C;&#x6BD5;&#xFF0C;&#x518D;&#x5173;&#x95ED;&#x6240;&#x6709;&#x7EBF;&#x7A0B;&#x6C60;&#x5F80;&#x4E0B;&#x8FD0;&#x884C;
for i in list:
    print(i.result())

基本同线程池,不同的是以下部分:

1.&#x5BFC;&#x5165;&#x8FDB;&#x7A0B;&#x6C60;/&#x7EBF;&#x7A0B;&#x6C60;&#x6A21;&#x5757;
from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor
import time,os

pool = ProcessPoolExecutor(5)  # &#x4E0D;&#x4F20;&#x9ED8;&#x8BA4;&#x662F;cpu&#x7684;&#x4E2A;&#x6570;

def task(name):
    print('%s&#x6765;&#x4E86;'% name)
    time.sleep(2)

call_back&#x51FD;&#x6570;&#x91CC;&#x9762;&#x9700;&#x8981;&#x4F20;&#x4E00;&#x4E2A;&#x53C2;&#x6570;&#xFF0C;&#x8BE5;&#x53C2;&#x6570;&#x5C31;&#x662F;res&#xFF08;&#x4E00;&#x4E2A;future&#x5BF9;&#x8C61;&#xFF09;
def call_back(n):
    # &#x53EF;&#x4EE5;&#x901A;&#x8FC7;n.result()&#x7684;&#x65B9;&#x6CD5;&#x83B7;&#x53D6;task&#x51FD;&#x6570;&#x7684;&#x8FD4;&#x56DE;&#x503C;
    print(n.result())

if __name__ == '__main__':
    for i in range(20):
        # add_done_callback&#x65B9;&#x6CD5;&#x662F;&#x7ED9;submit&#x8FD9;&#x4E2A;&#x5F02;&#x6B65;&#x63D0;&#x4EA4;&#x6DFB;&#x52A0;&#x4E00;&#x4E2A;&#x56DE;&#x8C03;&#x673A;&#x5236;&#xFF0C;&#x5B8C;&#x6210;&#x4EFB;&#x52A1;&#x4E4B;&#x540E;&#x7ACB;&#x523B;&#x56DE;&#x8C03;&#x7ED3;&#x679C;&#xFF0C;&#x65B9;&#x6CD5;&#x7684;&#x53C2;&#x6570;&#x662F;&#x4E00;&#x4E2A;&#x51FD;&#x6570;
        res = pool.submit(task, i).add_done_callback(call_back)

协程其实就是一种在单线程下实现并发的操作,程序猿通过检测自己写的代码,一旦遇到了IO操作的代码,我们就编写代码进行切换,这样使得cpu一直处于运行状态,提高程序的运行效率!

gevent模块的引用时为了使得函数之间不断的切换+保存状态!!

"""
&#x4F7F;&#x7528;&#x534F;&#x7A0B;&#xFF0C;&#x5C31;&#x5FC5;&#x987B;&#x8981;&#x6211;&#x4EEC;&#x901A;&#x8FC7;&#x4EE3;&#x7801;&#x5B9E;&#x65F6;&#x68C0;&#x6D4B;&#x7A0B;&#x5E8F;&#x662F;&#x5426;&#x8FDB;&#x5165;&#x5230;&#x4E86;IO&#x64CD;&#x4F5C;&#xFF0C;&#x5982;&#x679C;&#x8FDB;&#x5165;&#x4E86;IO&#x64CD;&#x4F5C;&#xFF0C;
&#x5C31;&#x8FDB;&#x884C;&#x5FEB;&#x901F;&#x7684;&#x5207;&#x6362;&#xFF0C;&#x4EE5;&#x6B64;&#x6765;&#x5B9E;&#x73B0;&#x5E76;&#x53D1;&#x7684;&#x6548;&#x679C;&#xFF0C;&#x63D0;&#x5347;&#x7A0B;&#x5E8F;&#x7684;&#x8FD0;&#x884C;&#x6548;&#x7387;
"""
1.&#x5BFC;&#x5165;gevent&#x6A21;&#x5757;&#x7684;spawn&#x6A21;&#x5757;&#xFF0C;&#x8BE5;&#x6A21;&#x5757;&#x662F;&#x7528;&#x6765;&#x76D1;&#x6D4B;&#x51FD;&#x6570;&#x91CC;&#x9762;&#x7684;IO&#x64CD;&#x4F5C;&#x7684;&#xFF0C;&#x4F46;&#x662F;spawn&#x6A21;&#x5757;&#x662F;&#x65E0;&#x6CD5;&#x76D1;&#x6D4B;&#x4E00;&#x4E9B;&#x5E38;&#x89C1;&#x7684;IO&#x64CD;&#x4F5C;&#x7684;
&#x56E0;&#x6B64;&#xFF0C;&#x9700;&#x8981;&#x5BFC;&#x5165;gevent&#x6A21;&#x5757;&#x4E2D;&#x7684;monkey&#x6A21;&#x5757;&#xFF0C;&#x4EE5;&#x6B64;&#x6765;&#x76D1;&#x6D4B;&#x6240;&#x6709;&#x7684;IO&#x64CD;&#x4F5C;
from gevent import monkey,spawn
monkey.patch_all()  # &#x7334;&#x5B50;&#x8865;&#x4E01;
import time

def func1():
    print('hhh')
    time.sleep(2)
    print('lalala')

def func2():
    print('wwww')
    time.sleep(3)
    print('&#x7ED3;&#x675F;')

start_time = time.time()
g1 = spawn(func1) # spawn&#x62EC;&#x53F7;&#x91CC;&#x662F;&#x9700;&#x8981;&#x542F;&#x52A8;&#x76D1;&#x6D4B;&#x7684;&#x51FD;&#x6570;&#x540D;&#xFF0C;&#x51FD;&#x6570;&#x540D;&#x540E;&#x9762;&#x53EF;&#x4EE5;&#x52A0;&#x9700;&#x8981;&#x4F20;&#x5165;&#x7684;&#x53C2;&#x6570;
g2 = spawn(func2) # &#x8BE5;&#x65B9;&#x6CD5;&#x662F;&#x5F02;&#x6B65;&#x63D0;&#x4EA4;&#xFF0C;&#x6709;&#x4E00;&#x4E2A;&#x8FD4;&#x56DE;&#x503C;&#xFF0C;&#x5982;&#x679C;&#x6CA1;&#x6709;join&#x65B9;&#x6CD5;&#x4F1A;&#x81EA;&#x52A8;&#x5F80;&#x4E0B;&#x6267;&#x884C;&#x4EE3;&#x7801;&#xFF0C;&#x7ED3;&#x675F;&#x7A0B;&#x5E8F;
g2.join() # &#x7B49;&#x5F85;&#x51FD;&#x6570;&#x6267;&#x884C;&#x5B8C;&#x5728;&#x5F80;&#x4E0B;&#x6267;&#x884C;
g1.join()
print(time.time()-start_time)

Original: https://www.cnblogs.com/suncolor/p/16632422.html
Author: 等日落
Title: 进程、线程补充与协程相关介绍

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/498583/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • Pandas写入Excel函数——to_excel 技术总结

    Pandas作为Python数据分析的一个常用包,经常会与Excel交互。最近经常使用pandas的 to_excel函数,发现坑还不少。经常报错,覆盖写入,让人烦躁。甚至Run一…

    Python 2023年8月17日
    088
  • 归纳整理:图表的基本组成元素对应的matplotlib库中的方法

    归纳整理:图表的基本组成元素对应的matplotlib库中的方法 目录 * – 零、前言 – 一、表格化归纳整理结果 – 二、图表的基本组成元素…

    Python 2023年9月6日
    056
  • 基于NumPy的数组重塑与转置

    这次主要是利用Python的:NumPy NumPy是引入了数组;数组是一些相同类型的数据的集合。 这些数据按照一定的顺序排列,每个数据占用大小相同的存储空间 数组的重塑是指更改数…

    Python 2023年8月27日
    040
  • 在无聊的时候玩小游戏

    Hi~ o( ̄▽ ̄)ブ我是闪电,今天给大家分享一个小游戏的完整代码(python3.6.5版本): import pygame from pygame import locals …

    Python 2023年9月20日
    025
  • 如何从DataFrame中选择一列数据

    查看数据 import pandas as pd movie= pd.read_csv(‘movie.csv’) movie.head() RankTitleGenreDescri…

    Python 2023年8月8日
    032
  • django 静态文件static路径没问题,就是加载不了框架

    在我学习jango的过程中我按照正常情况在前导入{% load static %} 然后在插入 再然后就在bootstrap网站导入框架。如图所示 {% load static %…

    Python 2023年8月5日
    069
  • 基于改进粒子群的柔性作业车间调度问题优化研究(Python代码实现)

    💥💥💞💞 欢迎来到本博客❤️❤️💥💥 🏆博主优势: 🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️ 座右铭:行百里者,半于九十。 目录💥1 概述📚2 运行结果🎉3 …

    Python 2023年8月23日
    057
  • python游戏代码解析

    目录 class self init “””,#,//,-> 初始化数组 append 关于图片的代码解释 python文件的使用方法 s…

    Python 2023年9月22日
    038
  • DiskGenius磁盘分区软件使用教程,磁盘扩容无损备份

    前几天,因为我的笔记本电脑C盘D盘全红了,趁着双11固态降价,赶紧买了一张三星980 500g 给我的拯救者插上了,加上原来的500g,总共1T,已经够用了。 不得不说拯救者系列预…

    Python 2023年10月16日
    054
  • pytest安装+使用+配置

    使用pytest编写用例需要遵循的规则:1、.py测试用例文件必须以test_开头或以_test结尾。2、测试用例类必须以Test开头,而且类中不能有构造方法( init())3、…

    Python 2023年9月12日
    035
  • 聊聊Vim的工作原理

    聊聊Vim的工作原理 日常里一直在用Vim这个编辑器,前阵子学习关于Linux中的fd(文件描述符)时,发现vim的进程描述符会比上一个自动加一,后续了解到vim的工作原理后,解开…

    Python 2023年10月20日
    051
  • kernel 启动流程

    一、概述 之前学习了uboot的启动流程,现在接着学习uboot的启动流程,关于 kernel 的启动流程分析的大佬也是很多的,这里还是通过流程的图的方式进行记录,为了像我一样的新…

    Python 2023年10月12日
    038
  • Python的22个万用公式,你确定不看看吗

    前言 在大家的日常python程序的编写过程中,都会有自己解决某个问题的解决办法,或者是在程序的调试过程中,用来帮助调试的程序公式。 小编通过几十万行代码的总结处理,总结出了22个…

    Python 2023年11月8日
    046
  • matplotlib: 有关 Backend 的说明

    matplotlib: 有关 Backend 的说明 什么是Backend? Matplotlib针对许多不同的用例和输出格式。 有些人在python shell中交互式地使用Ma…

    Python 2023年9月4日
    065
  • Flask 学习-85.Flask-SQLAlchemy 多个不确定条件查询

    在后台管理数据的时候,经常会有多个条件查询,查询参数可以是一个也可以是多个,如果没有查询参数就返回全部数据。 SQLAlchemy 使用query查询的时,可以使用filter()…

    Python 2023年8月9日
    072
  • ubuntu18.04更换apt源为阿里源

    备份原始source.list cp /etc/apt/sources.list /etc/apt/sources.list.back 更新sources内容 deb http:/…

    Python 2023年6月6日
    075
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球