开启多进程
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | def run_multi_camera_in_a_window(user_name,user_pwd,camera_ip_l,camera_Location): #开始创建进程 mp.set_start_method(method = 'spawn' ) # init 定义进程的启动程序模式 #队列池 queues = [mp.Queue(maxsize = 2 ) for _ in camera_ip_l] #队列池 每个进程一个 #开启次进程-1显示采集画面 processes = [mp.Process(target = image_collect, args = (queues, camera_ip_l,camera_Location))] #开启次进程-2采集进程 for queue, camera_ip in zip (queues, camera_ip_l): processes.append(mp.Process(target = image_put, args = (queue, user_name, user_pwd, camera_ip))) #设置所有进程为伴随进程 for process in processes: process.daemon = True # 如果设为True,代表p为后台运行的守护进程,当p的父进程终止时,p也随之终止,并且设定为True后,p不能创建自己的新进程 process.start() #for process in processes: #process.join() #父进程等待子进程结束后才开始执行自己的代码 processes[ 0 ].join() #主进程等待显示进程关闭后在执行后面代码(自动关闭)。其余采集进程会跟随主进程关闭而关闭。 for process in processes: if process.is_alive(): process.terminate() #强行关闭 print ( "关闭进程:" ,process.pid) |
1树莓派有四个内核,但是使用线程实际上还是在一个核心。但是使用进程可以解决问题。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | #方法一 直接调用 import time import random from multiprocessing import Process def run(name): print ( '%s runing' % name) time.sleep(random.randrange( 1 , 5 )) print ( '%s running end' % name) p1 = Process(target = run,args = ( 'anne' ,)) #必须加,号 p2 = Process(target = run,args = ( 'alice' ,)) p3 = Process(target = run,args = ( 'biantai' ,)) p4 = Process(target = run,args = ( 'haha' ,)) p1.deamon = True #伴随主进程关闭而关闭 p2.deamon = True p3.deamon = True p4.deamon = True p1.start() p2.start() p3.start() p4.start() print ( '主线程' ) |
https://www.jianshu.com/p/7ac73e9c7150
运行和停止
要停止一个进程实例,可以调用方法terminate
:
1 | p.terminate() |
但是通过执行系统命令ps
查看停止后的进程, 你会发现, 直接调用terminate
方法停止的进程变成了一个僵尸进程(defunct), 只能等待主程序退出, 这个僵尸进程才会消失.
通过在terminate
后添加一次调用join
方法等待进程真正结束, 就能避免出现僵尸进程:
1 | p.join() |
程序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | import time from multiprocessing import Process def run_forever(): while 1 : print (time.time()) time.sleep( 2 ) def main(): p = Process(target = run_forever) p.start() print ( 'start a process.' ) time.sleep( 10 ) if p.is_alive: # stop a process gracefully p.terminate() print ( 'stop process' ) p.join() if __name__ = = '__main__' : main() |
样例
双串口读取传感器数据给共享内存
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | # -*- coding: utf-8 -* import serial import time from multiprocessing import Process, Value, Array #读取温度和湿度 def serial_th(num,arr): ser = serial.Serial( '/dev/ttyUSB1' , 115200 ) if ser.isOpen = = False : ser. open () # 打开串口 #ser.write(b"Raspberry pi is ready") try : while True : line = str (ser.readline()) fengefu = '-' a = line.strip().split(fengefu) # x.strip()#除去每行的换行符 按照:分割 tv = "".join(a[ 1 : 2 ] ).strip() # 去除空格 hv = "".join(a[ 3 : 4 ]).strip() # 去除空格 arr[ 0 ] = int (tv) arr[ 1 ] = int (hv) #print('t-'+str(arr[0])+"-h-"+str(arr[1])) #time.sleep(0.1) # 软件延时 except KeyboardInterrupt: ser.close() #读取温度和湿度 def serial_lmq29(num,arr): ser = serial.Serial( '/dev/ttyUSB0' , 115200 ) if ser.isOpen = = False : ser. open () # 打开串口 #ser.write(b"Raspberry pi is ready") try : while True : line = str (ser.readline()) fengefu = '-' a = line.strip().split(fengefu) # x.strip()#除去每行的换行符 按照:分割 mq2 = "".join(a[ 1 : 2 ] ).strip() # 去除空格 light = "".join(a[ 3 : 4 ]).strip() # 去除空格 mq9 = "".join(a[ 5 : 6 ]).strip() # 去除空格 #print(mq9) arr[ 2 ] = int (mq2) arr[ 3 ] = int (light) arr[ 4 ] = int (mq9) #print('mq2-'+ str(arr[2]) +'-lihgt-'+str(arr[3])+'-mq9-'+str(arr[4])) #time.sleep(0.1) # 软件延时 except KeyboardInterrupt: ser.close() num_share = Value( 'd' , 0.0 ) arr_share = Array( 'i' , range ( 5 )) p_wh = Process(target = serial_th, args = (num_share,arr_share)) p_wh.deamon = True #伴随主进程关闭而关闭 p_wh.start() p_l29 = Process(target = serial_lmq29, args = (num_share,arr_share)) p_l29.deamon = True p_l29.start() while 1 : # 打印共享内存数据 print (arr_share[:]) |
进程通信 共享内存
https://docs.python.org/zh-cn/3/library/multiprocessing.html
共享内存
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | from multiprocessing import Process, Value, Array def f(n, a): n.value = 3.1415927 for i in range ( len (a)): a[i] = - a[i] if __name__ = = '__main__' : num = Value( 'd' , 0.0 ) arr = Array( 'i' , range ( 10 )) p = Process(target = f, args = (num, arr)) p.start() p.join() print (num.value) print (arr[:]) |
创建 num
和 arr
时使用的 'd'
和 'i'
参数是 array
模块使用的类型的 typecode : 'd'
表示双精度浮点数, 'i'
表示有符号整数。这些共享对象将是进程和线程安全的。
为了更灵活地使用共享内存,可以使用 multiprocessing.sharedctypes
模块,该模块支持创建从共享内存分配的任意ctypes对象。
给进程起名字
目标函数都是 foo()
函数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | # 命名一个进程 import multiprocessing import time def foo(): name = multiprocessing.current_process().name print ( "Starting %s \n" % name) time.sleep( 3 ) print ( "Exiting %s \n" % name) if __name__ = = '__main__' : process_with_name = multiprocessing.Process(name = 'foo_process' , target = foo) process_with_name.daemon = True # 注意原代码有这一行,但是译者发现删掉这一行才能得到正确输出 process_with_default_name = multiprocessing.Process(target = foo) process_with_name.start() process_with_default_name.start() |
运行上面的代码,打开终端输入:
python naming_process.py
输出的结果如下:
$ python naming_process.py
Starting foo_process
Starting Process-2
Exiting foo_process
Exiting Process-2
python进程的状态及创建
https://blog.csdn.net/xlengji/article/details/81165370
关闭进程
https://blog.csdn.net/qq_28821995/article/details/82856217
首先,杀死进程的主要命令为ps,grep,kill这三个指令。
1、第一步是获取要监控进程的pid号:
def get_process_pid(name):
child = os.popen("ps -ef | grep "+name).readline()
response = child.split(' ')
print(response)
for i in range(2,20):
if response[i] != "":
pid_str = response[i]
print(i)
break
else:
pass
return pid_str
上面程序可以获取进程pid号,首先将得到的child进行分割,再循环监测去取进程pid号(name-要杀死的进程名称)
2、利用kill杀死进程:
pid = get_process_pid("xxx")
os.system('sudo kill -s 9'+pid)
ok! 杀死进程成功。
Python多线程和多进程的Join和daemon(守护)的用法
基本知识
下面仅以多线程为例:
首先需要明确几个概念:
知识点一:当一个进程启动之后,会默认产生一个主线程,因为线程是程序执行流的最小单元,当设置多线程时,主线程会创建多个子线程,在python中,默认情况下(其实就是setDaemon(False)),主线程执行完自己的任务以后,就退出了,此时子线程会继续执行自己的任务,直到自己的任务结束,例子见下面一。
知识点二:当我们使用setDaemon(True)方法,也就是设置子线程为守护线程时,主线程一旦执行结束,则全部线程全部被终止执行,可能出现的情况就是,子线程的任务还没有完全执行结束,就被迫停止,例子见下面二。
知识点三:此时join的作用就凸显出来了,join所完成的工作就是线程同步,即主线程任务结束之后,进入阻塞状态,一直等待其他的子线程执行结束之后,主线程再终止,例子见下面三。
知识点四:join有一个timeout参数:
当设置守护线程时,含义是主线程对于子线程等待timeout的时间将会杀死该子线程,最后退出程序。所以说,如果有10个子线程,全部的等待时间就是每个timeout的累加和。简单的来说,就是给每个子线程一个timeout的时间,让他去执行,时间一到,不管任务有没有完成,直接杀死。
没有设置守护线程时,主线程将会等待timeout的累加和这样的一段时间,时间一到,主线程结束,但是并没有杀死子线程,子线程依然可以继续执行,直到子线程全部结束,程序退出。
双串口
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
· 因为Apifox不支持离线,我果断选择了Apipost!