1.0 互斥锁和死锁

1.1 互斥锁

  1. 当多个线程想要同时修改某一个共享数据时,就需要进行同步控制。
  2. 某个线程要更改共享数据时,先将其锁定,此时资源的状态为"锁定",其他线程不能改变,只到该线程释放资源,将资源的状态变成"非锁定",其他的线程才能再次锁定该资源。
  3. 互斥锁保证了每次只有一个线程进行写入操作,从而保证了多线程情况下数据的正确性。
    如下:
import threadingnum = 100
#添加线程demo,并写入两个形参
def demo(count,suo1):#把num转为全局变量global num#锁定suo1.acquire()for i in range(count):num += 1#解锁suo1.release()print(f"demo---{num}")def demo2(count,suo2):global num#锁定suo2.acquire()for i in range(count):num += 1#解锁suo2.release()print(f"demo2---{num}")def main():#1.创建互斥锁start_s1 = threading.Lock()#创建多线程t1 = threading.Thread(target=demo,args=(1000000,start_s1))t2 = threading.Thread(target=demo2,args=(1000000,start_s1))#启动多线程,执行t1.start()t2.start()#守护子进程t1.join()t2.join()print(f"Thread----{num}")
if __name__ == '__main__':main()
打印结果:
demo---1000100
demo2---2000100
Thread----2000100

2.0 死锁

在线程间共享多个资源的时候,如果两个线程分别占有一部分资源并且同时等待对方的资源,就会造成死锁。

  1. 连续加多把锁,也会造成死锁(用RLOCK解决)
  2. 如下这种方式也会造成死锁
import threading
import timeclass MyThread1(threading.Thread):def run(self):# 对mutexA上锁mutexA.acquire()# mutexA上锁后,延时1秒,等待另外那个线程 把mutexB上锁print(self.name+'----do1---up----')time.sleep(1)# 此时会堵塞,因为这个mutexB已经被另外的线程抢先上锁了mutexB.acquire()print(self.name+'----do1---down----')mutexB.release()# 对mutexA解锁mutexA.release()class MyThread2(threading.Thread):def run(self):# 对mutexB上锁mutexB.acquire()# mutexB上锁后,延时1秒,等待另外那个线程 把mutexA上锁print(self.name+'----do2---up----')time.sleep(1)# 此时会堵塞,因为这个mutexA已经被另外的线程抢先上锁了mutexA.acquire()print(self.name+'----do2---down----')mutexA.release()# 对mutexB解锁mutexB.release()mutexA = threading.Lock()
mutexB = threading.Lock()if __name__ == '__main__':t1 = MyThread1()t2 = MyThread2()t1.start()t2.start()

避免死锁
• 程序设计时要尽量避免
• 添加超时时间等

3.0 线程同步

我们使用 threading.Condition() 完成线程同步。
使用方式如下:
cond = threading.Condition()
等待
cond.wait()
唤醒
cond.notify()

例一实现:
天猫精灵:小爱同学
小爱同学:在
天猫精灵:现在几点了?
小爱同学:你猜猜现在几点了

import threading
from threading import Condition
class TianMao(threading.Thread):def __init__(self,mutex,cond):super().__init__(name="天猫精灵")self.mutex = mutexself.cond = conddef run(self):# self.mutex.acquire()# print(f"{self.name}:小爱同学")# self.mutex.release()## self.mutex.acquire()# print(f"{self.name}:现在几点了?")# self.mutex.release()with self.cond:print(f"{self.name}:小爱同学")#1先等待cond.wait()cond.notify()print(f"{self.name}:现在几点了?")class XiAi(threading.Thread):def __init__(self,mutex,cond):super().__init__(name="小爱同学")self.mutex = mutexself.cond = conddef run(self):# self.mutex.acquire()# print(f"{self.name}:在")# self.mutex.release()## self.mutex.acquire()# print(f"{self.name}:你猜猜现在几点了?")# self.mutex.release()with self.cond:cond.notify()print(f"{self.name}:在")cond.wait()print(f"{self.name}:你猜猜现在几点了?")if __name__ == '__main__':mutex = threading.RLock()cond = threading.Condition()t1 = TianMao(mutex,cond)t2 = XiAi(mutex,cond)t1.start()t2.start()
输出的结果:
天猫精灵:小爱同学
小爱同学:在
天猫精灵:现在几点了?
小爱同学:你猜猜现在几点了?

4.0 多任务版UDP聊天

• 创建套接字
• 绑定本地信息
• 获取对方IP和端口
• 发送、接收
• 创建两个线程,去执行功能


import threading
import socket'''
• 创建套接字
• 绑定本地信息
• 获取对方IP和端口
• 发送、接收
• 创建两个线程,去执行功能
'''
def jie(udp_s):while True:recv_data = udp_s.recvfrom(1024)print(recv_data)def fa(udp_s,start_ip,start_prot):while True:send_data = input("请输入需要发送的数据:")udp_s.sendto(send_data.encode("gbk"),(start_ip,start_prot))def main():#创建套接字udp_s = socket.socket(family=socket.AF_INET,type=socket.SOCK_DGRAM)#绑定本地接口udp_s.bind(("192.168.1.2", 7080))#获取对方的IP端口start_ip = input("请输入对方的ip:")start_prot = int(input("请输入对方的端口号:"))# jie(udp_s)# fa(udp_s,start_ip,start_prot)start_s1 = threading.Thread(target=jie,args=(udp_s,))start_s2 = threading.Thread(target=fa, args=(udp_s,start_ip,start_prot))start_s1.start()start_s2.start()if __name__ == '__main__':main()

5.0 进程

进程定义:

  1. 进程是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位。
  2. 是操作系统结构的基础。并且进程是线程的容器。
  3. 程序是指令、数据及其组织形式的描述,进程是程序的实体。

进程概念:
• 进程是一个实体。每一个进程都有它自己的地址空间,一般情况下,包括文本区域(text region)、数据区域(data region)和堆栈(stack region)。
• 进程是一个“执行中的程序”。
• 进程是操作系统中最基本、重要的概念。

进程与程序区别:
• 进程:正在执行的程序。动态的,暂时的
• 程序:没有执行的代码,是一个静态的,永久的

Python实现多进程
通过 multiprocessing.Process模块
• group:参数未使用,默认值为None。
• target:表示调用对象,即子进程要执行的任务。
• args:表示调用的位置参数元祖。
• kwargs:表示调用对象的字典。
• name:子进程名称

import multiprocessing
import time
def demo1():for i in range(3):print("demo1")time.sleep(1)
def demo2():for i in range(3):print("demo2")time.sleep(1)
def main():t1 = multiprocessing.Process(target=demo1)t2 = multiprocessing.Process(target=demo2)t1.start()t2.start()
if __name__ == '__main__':main()

通过继承Process类创建进程

import multiprocessing #创建进程的模块
import timeclass A(multiprocessing.Process):def run(self):for i in range(5):print("---1---")time.sleep(1)
class B(multiprocessing.Process):def run(self):for i in range(5):print("---2---")time.sleep(1)
if __name__ == '__main__':t1 = A()t2 = B()t1.daemon:True   #守护主进程,进程中使用的是daemon的# t1.daemon:Truet1.start()t2.start()# t1.join()# t2.join()print("主程序")

进程与线程区别:
• 根本区别
• 进程:操作系统资源分配的基本单位
• 线程:任务调度和执行的基本单位
• 开销
• 进程:通过复制代码+资源创建子进程 每个进程都有独立的代码和数据空间,程序之间的切换会有较大的开销
• 线程:在同一份代码里 创建线程 共享内存 开销较小
• 分配内存
• 进程:系统在运行的时候为每个进程分配不同的内存空间
• 线程:线程所使用的资源是它所属的进程的资源
• 包含关系
• 进程:一个进程可以拥有多个线程
• 线程:线程是进程的一部分

Python高级编程技巧-线程与进程(进阶讲解)相关推荐

  1. 《转载》Python并发编程之线程池/进程池--concurrent.futures模块

    本文转载自 Python并发编程之线程池/进程池--concurrent.futures模块 一.关于concurrent.futures模块 Python标准库为我们提供了threading和mul ...

  2. python网络编程基础(线程与进程、并行与并发、同步与异步、阻塞与非阻塞、CPU密集型与IO密集型)...

    python网络编程基础(线程与进程.并行与并发.同步与异步.阻塞与非阻塞.CPU密集型与IO密集型) 目录 线程与进程并行与并发同步与异步阻塞与非阻塞CPU密集型与IO密集型 线程与进程 进程 前言 ...

  3. Python并发编程之线程池/进程池

    引言 Python标准库为我们提供了threading和multiprocessing模块编写相应的多线程/多进程代码,但是当项目达到一定的规模,频繁创建/销毁进程或者线程是非常消耗资源的,这个时候我 ...

  4. python高级编程技巧

    个人博客点这里 如何在列表,字典,集合中根据条件筛选数据 方法1:通过迭代来进行判断筛选 解决方案 函数式编程: 如何统计序列中元素的出现频度 解决方案:使用collections.Counter对象 ...

  5. Python高级-编程技巧-1.3 Python垃圾回收及性能分析

    目录 通过实例方法名字的字符串调用方法 经典的参数错误 内存与内存管理简介(了解) 内存是什么? 操作系统的内存管理 进程内的内存管理 内存分配 内存池机制 缓冲池机制 垃圾回收机制 介绍 OS模块 ...

  6. python高级编程知识点_(转)python 高级编程技巧学习笔记

    转自https://www.jianshu.com/p/104cec085611,部分图出不来,mark一下,关键时候供查看. 第二章 数据结构相关话题 2.1.筛选数据 两种方式 filter函数: ...

  7. python高级应用_Python高级编程技巧

    Python 高级编程技巧 本文展示一些高级的 Python 设计结构和它们的使用方法.在日常工作中,你可以根据需要 选择合适的数据结构, 例如对快速查找性的要求. 对数据一致性的要求或是对索引的要求 ...

  8. python高级语法装饰器_Python高级编程——装饰器Decorator超详细讲解上

    Python高级编程--装饰器Decorator超详细讲解(上篇) 送你小心心记得关注我哦!! 进入正文 全文摘要 装饰器decorator,是python语言的重要特性,我们平时都会遇到,无论是面向 ...

  9. python队列线程池_实例详解:python高级编程之消息队列(Queue)与进程池(Pool)

    今天为大家带来的内容是:python高级编程之消息队列(Queue)与进程池(Pool),结合了实例的形式详细分析了Python消息队列与进程池的相关原理.使用技巧与操作注意事项!!! Queue消息 ...

最新文章

  1. Docker核心技术之Docker Compose
  2. javascript2秒后再执行_停车后5秒,车祸发生了!高速公路上你别再这样做了!| 一线微观...
  3. 《我想进大厂》之mysql夺命连环13问
  4. linux temp文件夹在哪_Win10系统下使用linux命令的方法
  5. Docker Compose 配置文件详解
  6. [HEOI2016/TJOI2016]排序
  7. python 网络编程 socket 报错 ConnectionResetError: [WinError 10054] 远程主机强迫关闭了一个现有的连接。
  8. 8.Hadoop的学习(Hadoop的配置--搭建完全分布式)
  9. proxy跨域不生效_vue前后端端口号不同,proxytable代理跨域无效
  10. 内存泄漏(OOM)产生原因
  11. python面向窗体的开发_Python高级进阶#019 pyqt5菜单menu应用,新建多窗体
  12. rust怎么上邮轮_20年内泰坦尼克号将消失 英公司推三千米沉船之旅
  13. winform调用SSH2访问linux,使用Cygwin通过ssh命令行来访问Windows 7
  14. 程序员是如何做到随时随地编程的?
  15. 用.net改写的uploadify多文件上传控件
  16. UNIX网络编程 第1卷 数据分享
  17. 神经元人体分布大图,人体的神经元图片
  18. el-descriptions
  19. Linux系统安装教程(非双系统/虚拟机安装教程)
  20. 卡普雷卡与西西弗斯.C

热门文章

  1. 英语名词格‘s和s‘的用法
  2. 计算机游戏攻略32关,保卫萝卜3单机版工厂关卡第32关详细攻略
  3. appserv 部署php,在Windows下应用AppServ快速配置PHP开发环境
  4. CentOS 安装多种×××打造Linux的全能播放器
  5. duilib仿百度网盘界面
  6. android8.1增大状态栏图标,转载▏手机状态栏看不懂的8个小图标,答案都在这里了!...
  7. html怎么在文本框设置提示语,input输入框提示语
  8. 两个LinearLayout或者ConstraintLayout平分布局
  9. 漫谈程序员系列:千奇百怪的程序员
  10. 缩短NC6服务启动的时间