50 python使用进程 python进程的状态及创建 Python多线程和多进程的Join和daemon(守护)的用法

50 python使用进程
python进程的状态及创建
Python多线程和多进程的Join和daemon(守护)的用法

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

共享内存

可以使用 Value 或 Array 将数据存储在共享内存映射中。例如,以下代码:

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


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的累加和这样的一段时间,时间一到,主线程结束,但是并没有杀死子线程,子线程依然可以继续执行,直到子线程全部结束,程序退出。

双串口