
1树莓派有四个内核,但是使用线程实际上还是在一个核心。但是使用进程可以解决问题。
#方法一 直接调用
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:
p.terminate()
但是通过执行系统命令ps查看停止后的进程, 你会发现, 直接调用terminate方法停止的进程变成了一个僵尸进程(defunct), 只能等待主程序退出, 这个僵尸进程才会消失.
通过在terminate后添加一次调用join方法等待进程真正结束, 就能避免出现僵尸进程:
p.join()
程序
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()
样例
双串口读取传感器数据给共享内存
# -*- 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
共享内存
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() 函数。
# 命名一个进程
import multiprocessing
import time
def foo():
name = multiprocessing.current_process().name
print("Starting %s
" % name)
time.sleep(3)
print("Exiting %s
" % 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的累加和这样的一段时间,时间一到,主线程结束,但是并没有杀死子线程,子线程依然可以继续执行,直到子线程全部结束,程序退出。
双串口