【神行百里】python开启多线程(threading)与多进程(multiprocessing)运行

  由于处理数据过多,程序运行很慢,就学习了一下python开启多线程与多进程的方法,虽然最后也没用上,但还是记录总结一下,以备不时之需。

  传送门:进程与线程认识,进程与线程通俗理解
  简言之,进程为资源分配的最小单元,线程为程序执行的最小单元


1. threading库实现多线程运行

  threading库中的Thread类可以方便地开启多线程运行,Thread类需要传入两个参数,target为需要执行的函数,args为函数的参数,本例中自定义的multithreading函数具有三个参数。

import threading
import time
import os

def multithreading(data, clss, k):
    for i in range(5):
        time.sleep(3 * (k + 1))
        print(k, ":", clss, "--->", data,
              "---> 线程id:", threading.get_ident(),
              "---> 进程id:", os.getpid())

data = ["一念月落,一念身错,一念关山难涉过。棋逢过客,执子者不问因果。",
        "奉上,唯愿去踏破善恶之叠浪,一心并肩赴跌宕",
        "刺予我伤口,重生了魂魄,立剑的时候,疾骤的嘶吼"]
clss = ["一念关山", "奉上", "立剑"]

threads = []
for k in range(3):
    t = threading.Thread(target=multithreading, args=(data[k], clss[k], k))  # 创建实例
    threads.append(t)  
    t.start()  # 启动线程运行

for t in threads:
    t.join()   # 等待所有线程执行完成

  输出如下,三句话的线程id不同,但进程id一样。不同的线程抢占cpu资源,导致三句话打印混乱,由于延时差异,“立剑” 线程最后完成。

0 : 一念关山 ---> 一念月落,一念身错,一念关山难涉过。棋逢过客,执子者不问因果。 ---> 线程id: 8956 ---> 进程id: 1268
0 : 一念关山 ---> 一念月落,一念身错,一念关山难涉过。棋逢过客,执子者不问因果。 ---> 线程id: 8956 ---> 进程id: 1268
1 : 奉上 ---> 奉上,唯愿去踏破善恶之叠浪,一心并肩赴跌宕 ---> 线程id: 5640 ---> 进程id: 1268
2 : 立剑 ---> 刺予我伤口,重生了魂魄,立剑的时候,疾骤的嘶吼 ---> 线程id: 26068 ---> 进程id: 1268
0 : 一念关山 ---> 一念月落,一念身错,一念关山难涉过。棋逢过客,执子者不问因果。 ---> 线程id: 8956 ---> 进程id: 1268
1 : 奉上 ---> 奉上,唯愿去踏破善恶之叠浪,一心并肩赴跌宕 ---> 线程id: 5640 ---> 进程id: 1268
0 : 一念关山 ---> 一念月落,一念身错,一念关山难涉过。棋逢过客,执子者不问因果。 ---> 线程id: 8956 ---> 进程id: 1268
0 : 一念关山 ---> 一念月落,一念身错,一念关山难涉过。棋逢过客,执子者不问因果。 ---> 线程id: 8956 ---> 进程id: 1268
2 : 立剑 ---> 刺予我伤口,重生了魂魄,立剑的时候,疾骤的嘶吼 ---> 线程id: 26068 ---> 进程id: 1268
1 : 奉上 ---> 奉上,唯愿去踏破善恶之叠浪,一心并肩赴跌宕 ---> 线程id: 5640 ---> 进程id: 1268
1 : 奉上 ---> 奉上,唯愿去踏破善恶之叠浪,一心并肩赴跌宕 ---> 线程id: 5640 ---> 进程id: 1268
2 : 立剑 ---> 刺予我伤口,重生了魂魄,立剑的时候,疾骤的嘶吼 ---> 线程id: 26068 ---> 进程id: 1268
1 : 奉上 ---> 奉上,唯愿去踏破善恶之叠浪,一心并肩赴跌宕 ---> 线程id: 5640 ---> 进程id: 1268
2 : 立剑 ---> 刺予我伤口,重生了魂魄,立剑的时候,疾骤的嘶吼 ---> 线程id: 26068 ---> 进程id: 1268
2 : 立剑 ---> 刺予我伤口,重生了魂魄,立剑的时候,疾骤的嘶吼 ---> 线程id: 26068 ---> 进程id: 1268

  


2. multiprocessing库实现多进程运行

  multiprocessing库使用方法与threading库相同,其开启类为Process。

  不过多进程运行似乎在windows下运行有点问题,参考 这篇文章 也没解决,似乎是windows下可以执行但无法显示,不过在linux下是可以显示的。

import threading
import multiprocessing
import time
import os

def my_multiprocess(data, clss, k):
    for i in range(5):
        time.sleep(3 * (k + 1))
        print(k, ":", clss, "--->", data,
              "---> 线程id:", threading.get_ident(),
              "---> 进程id:", os.getpid())

data = ["一念月落,一念身错,一念关山难涉过。棋逢过客,执子者不问因果。",
        "奉上,唯愿去踏破善恶之叠浪,一心并肩赴跌宕",
        "刺予我伤口,重生了魂魄,立剑的时候,疾骤的嘶吼"]
clss = ["一念关山", "奉上", "立剑"]

processes = []
for k in range(3):
    p = multiprocessing.Process(target=my_multiprocess, args=(data[k], clss[k], k))
    processes.append(p)
    p.start()

for p in processes:
    p.join()

  linux下运行的输出如下,三句话的进程id不同,但线程id一样了,这是可以的,线程id只要保证在进程中的唯一性就可以啦~

0 : 一念关山 ---> 一念月落,一念身错,一念关山难涉过。棋逢过客,执子者不问因果。 ---> 线程id: 140066568185664 ---> 进程id: 1889018
0 : 一念关山 ---> 一念月落,一念身错,一念关山难涉过。棋逢过客,执子者不问因果。 ---> 线程id: 140066568185664 ---> 进程id: 1889018
1 : 奉上 ---> 奉上,唯愿去踏破善恶之叠浪,一心并肩赴跌宕 ---> 线程id: 140066568185664 ---> 进程id: 1889019
0 : 一念关山 ---> 一念月落,一念身错,一念关山难涉过。棋逢过客,执子者不问因果。 ---> 线程id: 140066568185664 ---> 进程id: 1889018
2 : 立剑 ---> 刺予我伤口,重生了魂魄,立剑的时候,疾骤的嘶吼 ---> 线程id: 140066568185664 ---> 进程id: 1889020
0 : 一念关山 ---> 一念月落,一念身错,一念关山难涉过。棋逢过客,执子者不问因果。 ---> 线程id: 140066568185664 ---> 进程id: 1889018
1 : 奉上 ---> 奉上,唯愿去踏破善恶之叠浪,一心并肩赴跌宕 ---> 线程id: 140066568185664 ---> 进程id: 1889019
0 : 一念关山 ---> 一念月落,一念身错,一念关山难涉过。棋逢过客,执子者不问因果。 ---> 线程id: 140066568185664 ---> 进程id: 1889018
2 : 立剑 ---> 刺予我伤口,重生了魂魄,立剑的时候,疾骤的嘶吼 ---> 线程id: 140066568185664 ---> 进程id: 1889020
1 : 奉上 ---> 奉上,唯愿去踏破善恶之叠浪,一心并肩赴跌宕 ---> 线程id: 140066568185664 ---> 进程id: 1889019
1 : 奉上 ---> 奉上,唯愿去踏破善恶之叠浪,一心并肩赴跌宕 ---> 线程id: 140066568185664 ---> 进程id: 1889019
2 : 立剑 ---> 刺予我伤口,重生了魂魄,立剑的时候,疾骤的嘶吼 ---> 线程id: 140066568185664 ---> 进程id: 1889020
1 : 奉上 ---> 奉上,唯愿去踏破善恶之叠浪,一心并肩赴跌宕 ---> 线程id: 140066568185664 ---> 进程id: 1889019
2 : 立剑 ---> 刺予我伤口,重生了魂魄,立剑的时候,疾骤的嘶吼 ---> 线程id: 140066568185664 ---> 进程id: 1889020
2 : 立剑 ---> 刺予我伤口,重生了魂魄,立剑的时候,疾骤的嘶吼 ---> 线程id: 140066568185664 ---> 进程id: 1889020

  


  so:多线程与多进程运行可以提高Python程序运行速度吗

  Python的全局解释器锁(GIL)限制了同一时刻只有一个线程可以执行Python字节码,对于计算密集型任务,多线程往往无法提高程序的执行速度,但对于IO密集型任务,多线程可以利用IO阻塞等待时的空闲时间执行其他线程,提升运行效率。
  多进程则可以有效地避免GIL的限制,允许同时执行多个进程,从而提高程序的执行速度。

你可能感兴趣的:(python,多线程运行,多进程运行)