Python进程、多进程、线程以及同步和死锁

news/2024/11/29 5:25:50/

一 传统编程的缺陷

传统编程的弊端:

# 必须按照顺序执行,多个任务无法同时在还行
import timedef sing():for i in range(5):print("sing: hero")time.sleep(1)       # 每唱一次,等1秒再唱def dance():for i in range(5):print("dance: swan")time.sleep(1)       # 每唱一次,等1秒再跳def main():sing()dance()if __name__ == "__main__":main()

2个任务花费的时间是10秒,如果要边跳边唱,其实2个任务是可以在最长的那个任务完成时全部完成的。

实现多任务编程的方式有很多,如:多进程、多线程、协程等。

二 使用多进程方式实现多任务

# 必须按照顺序执行,多个任务无法同时在还行
import time
import multiprocessingdef sing():for i in range(5):print("sing: hero")time.sleep(1)       # 每唱一次,等1秒再唱def dance():for i in range(5):print("dance: swan")time.sleep(1)       # 每唱一次,等1秒再跳def main():p1 = multiprocessing.Process(target=sing)p2 = multiprocessing.Process(target=dance)p1.start()p2.start()if __name__ == "__main__":main()

三 进程的一些操作

通过 htop 命令可以查看详细的进程列表。

注意:使用kill -9 pid 杀死主进程后,子进程不会被杀死,此时命令行也会无法正常退出,因为该命令的信号是发给了主进程来执行杀死任务,子进程由于没有父进程,变成了孤儿进程,之后被init进程领养。也就是说杀死主进程后,子进程的父进程称为了init进程。

通过 os.getpid() 可以获取到当前进程的pid,os.getppid()可以获取父进程id。

四 进程间通信

进程之间无法直接进行通信,因为他们是互相独立的应用程序。

进程之间要实现通信,常见的方式有:socket等,python中可以使用队列方式实现:

queue = multiprocessing.Queue(3)
queue.put("111")
queue.put(222)# 取数据
res = queue.get()
print(res)
# 判断: q.full()  q.empty()

五 进程池

p = multiprocessing.Pool(3)

六 多线程方式实现多任务

import time
import threadingdef sing():for i in range(5):print("sing: hero")time.sleep(1)       # 每唱一次,等1秒再唱def dance():for i in range(5):print("dance: swan")time.sleep(1)       # 每唱一次,等1秒再跳def main():t1 = threading.Thread(target=sing)      # 创建一个线程对象t2 = threading.Thread(target=dance)     # 创建一个线程对象t1.start()                              # 开启线程t2.start()                              # 开启线程if __name__ == "__main__":main()

七 线程相关API

通过 threading.Thread() 可以创建线程,threading.enumerate() 也可以查看当前所有的线程:

import time
import threadingdef sing():for i in range(5):print("sing: hero")time.sleep(1)       # 每唱一次,等1秒再唱def dance():for i in range(5):print("dance: swan")time.sleep(1)       # 每唱一次,等1秒再跳def main():t1 = threading.Thread(target=sing)t2 = threading.Thread(target=dance)t1.start()t2.start()while True:length = len(threading.enumerate())print("当前线程数为:%d" % length)if length <= 1:breaktime.sleep(0.5)if __name__ == "__main__":main()

八 同步与死锁

线程是共享全局变量的,这样就会造成数据的混乱:

import time
import threading# 定义共享的全局变量
num = 0def add100():global numfor i in range(100000):num = num + 0.00001def add1000():global numfor i in range(100000):num = num + 1000def main():t1 = threading.Thread(target=add100)t2 = threading.Thread(target=add1000)t1.start()t2.start()time.sleep(5)print(num)              # 每次输出的结果是不相同的if __name__ == "__main__":main()

使用互斥锁实现同步的方案:

import time
import threading# 定义共享的全局变量
num = 0def add100():global nummutex.acquire()     # 加锁:若已经加锁,则会直到锁被揭开for i in range(100000):num = num + 0.00001mutex.release()     # 解锁def add1000():global nummutex.acquire()     # 加锁:若已经加锁,则会直到锁被揭开for i in range(100000):num = num + 1000mutex.release()     # 解锁# 创建互斥锁,默认不会上锁
mutex = threading.Lock()def main():t1 = threading.Thread(target=add100)t2 = threading.Thread(target=add1000)t1.start()t2.start()time.sleep(5)print(num)          # 100000001.0 永远不会变if __name__ == "__main__":main()

http://www.ppmy.cn/news/1324089.html

相关文章

CC工具箱使用指南:【更改字段别名(属性映射)】

一、简介 在我工作中遇到的大多数图斑&#xff0c;字段名称一般是英文&#xff0c;字段别名是中文&#xff0c;使用起来是比较方便的。 但有时候数据经过分析处理过后&#xff0c;图斑的字段别名被修改成了和字段名称一样的英文&#xff0c;这样就很难理解字段名称的意思&…

Windows如何安装VNC+Viewer+cpolar实现远程Ubuntu桌面?

文章目录 前言1. ubuntu安装VNC2. 设置vnc开机启动3. windows 安装VNC viewer连接工具4. 内网穿透4.1 安装cpolar【支持使用一键脚本命令安装】4.2 创建隧道映射4.3 测试公网远程访问 5. 配置固定TCP地址5.1 保留一个固定的公网TCP端口地址5.2 配置固定公网TCP端口地址5.3 测试…

HarmonyOS —— buildMode 设置(对比 Android Build Varient)

前言 在安卓中 Build Variant 主要依赖模块&#xff08;module&#xff09;中 build.gradle 的 BuildType 和 ProductFlavor 提供的属性和方法&#xff0c;我们可以使用 Build Type 可以配置不同的构建方式、ProductFlavor 主要用来进行多渠道打包。 在鸿蒙中要做到同样像效果…

开发安全之:Database access control

Overview 如果没有适当的 access control&#xff0c;就会执行一个包含用户控制主键的 SQL 指令&#xff0c;从而允许攻击者访问未经授权的记录。 Details Database access control 错误在以下情况下发生&#xff1a; 1. 数据从一个不可信赖的数据源进入程序。 2. 这个数据用…

《WebKit 技术内幕》之三(3): WebKit 架构和模块

3 Webkit2 3.1 Webkit2 架构及模块 相比于狭义的WebKit&#xff0c;WebKit2是一套全新的结构和接口&#xff0c;而并不是一个简单的升级版。Webkit2 的思想同 Chrominum 类似&#xff0c;就是将渲染过程放在单独的进程中来完成&#xff0c;独立于用户界面。 webKit2中…

Python 语法糖

一、基本概念 语法糖&#xff0c;可以理解为&#xff1a;“甜蜜” 的便捷语法。 它是编程语言为程序提供的更简洁、更易读的语法实现的语法结构&#xff0c;它并不影响语言的功能&#xff0c;仅仅是一种更便捷的书写方式。 这就像你制作蛋糕时&#xff0c;使用现代烤箱而不是…

天锐绿盾有哪些功能?

天锐绿盾是一款企业内网安全管理软件&#xff0c;具有多种功能来保护企业的信息安全。 PC地址&#xff1a; https://isite.baidu.com/site/wjz012xr/2eae091d-1b97-4276-90bc-6757c5dfedee 以下是天锐绿盾的主要功能&#xff1a; 文件加密保护&#xff1a;天锐绿盾可以对文件…

力扣hot100 二叉树中的最大路径和 递归

Problem: 124. 二叉树中的最大路径和 文章目录 解题方法复杂度&#x1f496; Code 解题方法 &#x1f468;‍&#x1f3eb; 参考思路 复杂度 时间复杂度: O ( n ) O(n) O(n) 空间复杂度: O ( n ) O(n) O(n) &#x1f496; Code /*** Definition for a binary tree no…