环境

  • xubuntu 16.04
  • anaconda
  • pycharm
  • python3.6
  • https://www.cnblogs.com/jokerbj/p/7460260.html
  • http://www.dabeaz.com/python/UnderstandingGIL.pdf

多线程 vs 多进程

  • 程序:一堆代码以文本形式存入一个文档

  • 进程: 程序运行的一个状态

    • 包含地址空间,内存,数据栈等
    • 每个进程由自己完全独立的运行环境,多进程共享数据是一个问题
  • 线程

    • 一个进程的独立运行片段,一个进程可以由多个线程
    • 轻量化的进程
    • 一个进程的多个现成间共享数据和上下文运行环境
    • 共享互斥问题
  • 全局解释器锁(GIL)

    • Python代码的执行是由python虚拟机进行控制
    • 在主循环中稚嫩更有一个控制线程在执行
  • Python包

    • thread:有问题,不好用,python3改成了_thread

    • threading: 通行的包

    • 案例01: 顺序执行,耗时比较长

'''
利用time函数,生成两个函数
顺序调用
计算总的运行时间'''
import timedef loop1():# ctime 得到当前时间print('Start loop 1 at :', time.ctime())# 睡眠多长时间,单位是秒time.sleep(4)print('End loop 1 at:', time.ctime())def loop2():# ctime 得到当前时间print('Start loop 2 at :', time.ctime())# 睡眠多长时间,单位是秒time.sleep(2)print('End loop 2 at:', time.ctime())def main():print("Starting at:", time.ctime())loop1()loop2()print("All done at:", time.ctime())if __name__ == '__main__':main()

结果,顺序执行:

Starting at: Sun Aug 11 16:05:23 2019
Start loop 1 at : Sun Aug 11 16:05:23 2019
End loop 1 at: Sun Aug 11 16:05:27 2019
Start loop 2 at : Sun Aug 11 16:05:27 2019
End loop 2 at: Sun Aug 11 16:05:29 2019
All done at: Sun Aug 11 16:05:29 2019
  • 案例02: 改用多线程,缩短总时间,使用_thread
'''
利用time函数,生成两个函数
顺序调用
计算总的运行时间'''
import time
import _thread as threaddef loop1():# ctime 得到当前时间print('Start loop 1 at :', time.ctime())# 睡眠多长时间,单位是秒time.sleep(4)print('End loop 1 at:', time.ctime())def loop2():# ctime 得到当前时间print('Start loop 2 at :', time.ctime())# 睡眠多长时间,单位是秒time.sleep(2)print('End loop 2 at:', time.ctime())def main():print("Starting at:", time.ctime())# 启动多线程的意思是用多线程去执行某个函数# 启动多线程函数为start_new_thead# 参数两个,一个是需要运行的函数名,第二是函数的参数作为元祖使用,为空则使用空元祖# 注意:如果函数只有一个参数,需要参数后由一个逗号thread.start_new_thread(loop1, ())thread.start_new_thread(loop2, ())print("All done at:", time.ctime())if __name__ == '__main__':main()while True:time.sleep(1)

没有 while True:
time.sleep(1)
运行结果(不等其他线程完成,主线程就完成了):
有 while True:
time.sleep(1)
运行结果(主线程死等):

  • 案例03: 多线程,传参数
#利用time延时函数,生成两个函数
# 利用多线程调用
# 计算总运行时间
# 练习带参数的多线程启动方法
import time
# 导入多线程包并更名为thread
import _thread as threaddef loop1(in1):# ctime 得到当前时间print('Start loop 1 at :', time.ctime())# 把参数打印出来print("我是参数 ",in1)# 睡眠多长时间,单位是秒time.sleep(4)print('End loop 1 at:', time.ctime())def loop2(in1, in2):# ctime 得到当前时间print('Start loop 2 at :', time.ctime())# 把参数in 和 in2打印出来,代表使用print("我是参数 " ,in1 , "和参数  ", in2)# 睡眠多长时间,单位是秒time.sleep(2)print('End loop 2 at:', time.ctime())def main():print("Starting at:", time.ctime())# 启动多线程的意思是用多线程去执行某个函数# 启动多线程函数为start_new_thead# 参数两个,一个是需要运行的函数名,第二是函数的参数作为元祖使用,为空则使用空元祖# 注意:如果函数只有一个参数,需要参数后由一个逗号thread.start_new_thread(loop1,("王老大", ))thread.start_new_thread(loop2,("王大鹏", "王晓鹏"))print("All done at:", time.ctime())if __name__ == "__main__":main()# 一定要有while语句# 因为启动多线程后本程序就作为主线程存在# 如果主线程执行完毕,则子线程可能也需要终止while True:time.sleep(10)
  • threading的使用

    • 直接利用threading.Thread生成Thread实例

      1. t = threading.Thread(target=xxx, args=(xxx,))
      2. t.start():启动多线程
      3. t.join(): 等待多线程执行完成
      4. 案例04
#利用time延时函数,生成两个函数
# 利用多线程调用
# 计算总运行时间
# 练习带参数的多线程启动方法
import time
# 导入多线程处理包
import threadingdef loop1(in1):# ctime 得到当前时间print('Start loop 1 at :', time.ctime())# 把参数打印出来print("我是参数 ",in1)# 睡眠多长时间,单位是秒time.sleep(4)print('End loop 1 at:', time.ctime())def loop2(in1, in2):# ctime 得到当前时间print('Start loop 2 at :', time.ctime())# 把参数in 和 in2打印出来,代表使用print("我是参数 " ,in1 , "和参数  ", in2)# 睡眠多长时间,单位是秒time.sleep(2)print('End loop 2 at:', time.ctime())def main():print("Starting at:", time.ctime())# 生成threading.Thread实例t1 = threading.Thread(target=loop1, args=("王老大",))t1.start()t2 = threading.Thread(target=loop2, args=("王大鹏", "王小鹏"))t2.start()print("All done at:", time.ctime())if __name__ == "__main__":main()# 一定要有while语句# 因为启动多线程后本程序就作为主线程存在# 如果主线程执行完毕,则子线程可能也需要终止while True:time.sleep(10)


5. 案例05: 加入join后比较跟案例04的结果的异同

#利用time延时函数,生成两个函数
# 利用多线程调用
# 计算总运行时间
# 练习带参数的多线程启动方法
import time
# 导入多线程处理包
import threadingdef loop1(in1):# ctime 得到当前时间print('Start loop 1 at :', time.ctime())# 把参数打印出来print("我是参数 ",in1)# 睡眠多长时间,单位是秒time.sleep(4)print('End loop 1 at:', time.ctime())def loop2(in1, in2):# ctime 得到当前时间print('Start loop 2 at :', time.ctime())# 把参数in 和 in2打印出来,代表使用print("我是参数 " ,in1 , "和参数  ", in2)# 睡眠多长时间,单位是秒time.sleep(2)print('End loop 2 at:', time.ctime())def main():print("Starting at:", time.ctime())# 生成threading.Thread实例t1 = threading.Thread(target=loop1, args=("王老大",))t1.start()t2 = threading.Thread(target=loop2, args=("王大鹏", "王小鹏"))t2.start()t1.join()t2.join()print("All done at:", time.ctime())if __name__ == "__main__":main()# 一定要有while语句# 因为启动多线程后本程序就作为主线程存在# 如果主线程执行完毕,则子线程可能也需要终止while True:time.sleep(10)

运行结果:
Starting at: Sun Aug 11 16:19:40 2019
Start loop 1 at : Sun Aug 11 16:19:40 2019
我是参数 王老大
Start loop 2 at : Sun Aug 11 16:19:40 2019
我是参数 王大鹏 和参数 王小鹏
End loop 2 at: Sun Aug 11 16:19:42 2019
End loop 1 at: Sun Aug 11 16:19:44 2019
All done at: Sun Aug 11 16:19:44 2019

  • 守护线程-daemon
    - 如果在程序中将子线程设置成守护线程,则子线程会在主线程结束的时候自动退出
    - 一般认为,守护线程不重要或者不允许离开主线程独立运行
    - 守护线程案例能否有效果跟环境相关
    - 案例06非守护线程
import time
import threadingdef fun():print("Start fun")time.sleep(2)print("end fun")print("Main thread")t1 = threading.Thread(target=fun, args=() )
t1.start()time.sleep(1)
print("Main thread end")

  • 案例07守护线程
import time
import threadingdef fun():print("Start fun")time.sleep(2)print("end fun")print("Main thread")t1 = threading.Thread(target=fun, args=() )
# 社会守护线程的方法,必须在start之前设置,否则无效
t1.setDaemon(True)
#t1.daemon = True
t1.start()time.sleep(1)
print("Main thread end")


主线程dead,子线程也dead

  • 线程常用属性
    - threading.currentThread:返回当前线程变量
    - threading.enumerate:返回一个包含正在运行的线程的list,正在运行的线程指的是线程启动后,结束前的状态
    - threading.activeCount: 返回正在运行的线程数量,效果跟 len(threading.enumerate)相同
    - thr.setName: 给线程设置名字
    - thr.getName: 得到线程的名字
import time
import threadingdef loop1():# ctime 得到当前时间print('Start loop 1 at :', time.ctime())# 睡眠多长时间,单位是秒time.sleep(6)print('End loop 1 at:', time.ctime())def loop2():# ctime 得到当前时间print('Start loop 2 at :', time.ctime())# 睡眠多长时间,单位是秒time.sleep(1)print('End loop 2 at:', time.ctime())def loop3():# ctime 得到当前时间print('Start loop 3 at :', time.ctime())# 睡眠多长时间,单位是秒time.sleep(5)print('End loop 3 at:', time.ctime())def main():print("Starting at:", time.ctime())# 生成threading.Thread实例t1 = threading.Thread(target=loop1, args=( ))# setName是给每一个子线程设置一个名字t1.setName("THR_1")t1.start()t2 = threading.Thread(target=loop2, args=( ))t2.setName("THR_2")t2.start()t3 = threading.Thread(target=loop3, args=( ))t3.setName("THR_3")t3.start()# 预期3秒后,thread2已经自动结束,time.sleep(3)# enumerate 得到正在运行子线程,即子线程1和子线程3for thr in threading.enumerate():# getName能够得到线程的名字print("正在运行的线程名字是: {0}".format(thr.getName()))print("正在运行的子线程数量为: {0}".format(threading.activeCount()))print("All done at:", time.ctime())if __name__ == "__main__":main()# 一定要有while语句# 因为启动多线程后本程序就作为主线程存在# 如果主线程执行完毕,则子线程可能也需要终止while True:time.sleep(10)

  • 直接继承自threading.Thread

    - 直接继承Thread
    - 重写run函数
    - 类实例可以直接运行

    • 案例09
import threading
import time# 1. 类需要继承自threading.Thread
class MyThread(threading.Thread):def __init__(self, arg):super(MyThread, self).__init__()self.arg = arg# 2 必须重写run函数,run函数代表的是真正执行的功能def  run(self):time.sleep(2)print("The args for this class is {0}".format(self.arg))for i in range(5):t = MyThread(i)t.start()t.join()print("Main thread is done!!!!!!!!")

  • 案例10, 工业风案例
import threading
from time import sleep, ctimeloop = [4,2]class ThreadFunc:def __init__(self, name):self.name = namedef loop(self, nloop, nsec):''':param nloop: loop函数的名称:param nsec: 系统休眠时间:return:'''print('Start loop ', nloop, 'at ', ctime())sleep(nsec)print('Done loop ', nloop, ' at ', ctime())def main():print("Starting at: ", ctime())# ThreadFunc("loop").loop 跟一下两个式子相等:# t = ThreadFunc("loop")# t.loop# 以下t1 和  t2的定义方式相等t = ThreadFunc("loop")t1 = threading.Thread( target = t.loop, args=("LOOP1", 4))# 下面这种写法更西方人,工业化一点t2 = threading.Thread( target = ThreadFunc('loop').loop, args=("LOOP2", 2))# 常见错误写法#t1 = threading.Thread(target=ThreadFunc('loop').loop(100,4))#t2 = threading.Thread(target=ThreadFunc('loop').loop(100,2))t1.start()t2.start()t1.join( )t2.join()print("ALL done at: ", ctime())if __name__ == '__main__':main()

常用错误写法:
t1 = threading.Thread(target=ThreadFunc(‘loop’).loop(100,4))
t2 = threading.Thread(target=ThreadFunc(‘loop’).loop(100,2))

import threading
from time import sleep, ctimeloop = [4,2]class ThreadFunc:def __init__(self, name):self.name = namedef loop(self, nloop, nsec):''':param nloop: loop函数的名称:param nsec: 系统休眠时间:return:'''print('Start loop ', nloop, 'at ', ctime())sleep(nsec)print('Done loop ', nloop, ' at ', ctime())def main():print("Starting at: ", ctime())# ThreadFunc("loop").loop 跟一下两个式子相等:# t = ThreadFunc("loop")# t.loop# 以下t1 和  t2的定义方式相等t = ThreadFunc("loop")# 常见错误写法t1 = threading.Thread(target=ThreadFunc('loop').loop(100,4))t2 = threading.Thread(target=ThreadFunc('loop').loop(100,2))t1.start()t2.start()t1.join( )t2.join()print("ALL done at: ", ctime())if __name__ == '__main__':main()

错误结果:两个线程没有同时运行

  • 共享变量

    • 共享变量: 当多个线程同时访问一个变量的时候,会产生共享变量的问题
    • 案例11
import threadingsum = 0
loopSum = 1000000def myAdd():global  sum, loopSumfor i in range(1, loopSum):sum += 1def myMinu():global  sum, loopSumfor i in range(1, loopSum):sum -= 1if __name__ == '__main__':print("Starting ....{0}".format(sum))# 开始多线程的实例,看执行结果是否一样t1 = threading.Thread(target=myAdd, args=())t2 = threading.Thread(target=myMinu, args=())t1.start()t2.start()t1.join()t2.join()print("Done .... {0}".format(sum))

  • 解决变量:锁,信号灯,
  • 锁(Lock)
    • 是一个标志,表示一个线程在占用一些资源
    • 使用方法:
      • 定义lock = threading.Lock()
      • 上锁 lock.acquire()
      • 使用共享资源,放心的用
      • 取消锁,释放锁 lock.release()
    • 案例12
import threadingsum = 0
loopSum = 1000000lock = threading.Lock()def myAdd():global  sum, loopSumfor i in range(1, loopSum):# 上锁,申请锁lock.acquire()sum += 1# 释放锁lock.release()def myMinu():global  sum, loopSumfor i in range(1, loopSum):lock.acquire()sum -= 1lock.release()if __name__ == '__main__':print("Starting ....{0}".format(sum))# 开始多线程的实例,看执行结果是否一样t1 = threading.Thread(target=myAdd, args=())t2 = threading.Thread(target=myMinu, args=())t1.start()t2.start()t1.join()t2.join()print("Done .... {0}".format(sum))

  • 锁谁: 哪个资源需要多个线程共享,锁哪个
    - 理解锁:锁其实不是锁住谁,而是一个令牌

    • 线程安全问题:

      • 如果一个资源/变量,他对于多线程来讲,不用加锁也不会引起任何问题,则称为线程安全
      • 线程不安全变量类型: list, set, dict
      • 线程安全变量类型:queue 队列
    • 生产者消费者问题
      • 一个模型,可以用来搭建消息队列
      • queue是一个用来存放变量的数据结构,特点是先进先出,内部元素排队,可以理解成一个特殊的list
      • 案例13
#encoding=utf-8
import threading
import time# Python2
# from Queue import Queue# Python3
import queueclass Producer(threading.Thread):def run(self):global queuecount = 0while True:# qsize返回queue内容长度if queue.qsize() < 1000:for i in range(100):count = count +1msg = '生成产品'+str(count)# put是网queue中放入一个值queue.put(msg)print(msg)time.sleep(0.5)class Consumer(threading.Thread):def run(self):global queuewhile True:if queue.qsize() > 100:for i in range(3):# get是从queue中取出一个值msg = self.name + '消费了 '+queue.get()print(msg)time.sleep(1)if __name__ == '__main__':queue = queue.Queue()for i in range(500):queue.put('初始产品'+str(i))for i in range(2):p = Producer()p.start()for i in range(5):c = Consumer()c.start()

  • 死锁问题, 案例14
import threading
import timelock_1 = threading.Lock()
lock_2 = threading.Lock()def func_1():print("func_1 starting.........")lock_1.acquire()print("func_1 申请了 lock_1....")time.sleep(2)print("func_1 等待 lock_2.......")lock_2.acquire()print("func_1 申请了 lock_2.......")lock_2.release()print("func_1 释放了 lock_2")lock_1.release()print("func_1 释放了 lock_1")print("func_1 done..........")def func_2():print("func_2 starting.........")lock_2.acquire()print("func_2 申请了 lock_2....")time.sleep(4)print("func_2 等待 lock_1.......")lock_1.acquire()print("func_2 申请了 lock_1.......")lock_1.release()print("func_2 释放了 lock_1")lock_2.release()print("func_2 释放了 lock_2")print("func_2 done..........")if __name__ == "__main__":print("主程序启动..............")t1 = threading.Thread(target=func_1, args=())t2 = threading.Thread(target=func_2, args=())t1.start()t2.start()t1.join()t2.join()print("主程序启动..............")


func_1,func_2产生死锁

  • 锁的等待时间问题,案例15
  • lock_1.acquire(timeout=4)
  • rst = lock_2.acquire(timeout=2)
import threading
import timelock_1 = threading.Lock()
lock_2 = threading.Lock()def func_1():print("func_1 starting.........")lock_1.acquire(timeout=4)print("func_1 申请了 lock_1....")time.sleep(2)print("func_1 等待 lock_2.......")rst = lock_2.acquire(timeout=2)if rst:print("func_1 已经得到锁 lock_2")lock_2.release()print("func_1 释放了锁 lock_2")else:print("func_1 注定没申请到lock_2.....")lock_1.release()print("func_1 释放了 lock_1")print("func_1 done..........")def func_2():print("func_2 starting.........")lock_2.acquire()print("func_2 申请了 lock_2....")time.sleep(4)print("func_2 等待 lock_1.......")lock_1.acquire()print("func_2 申请了 lock_1.......")lock_1.release()print("func_2 释放了 lock_1")lock_2.release()print("func_2 释放了 lock_2")print("func_2 done..........")if __name__ == "__main__":print("主程序启动..............")t1 = threading.Thread(target=func_1, args=())t2 = threading.Thread(target=func_2, args=())t1.start()t2.start()t1.join()t2.join()print("主程序结束..............")

  • semphore 信号灯

    • 允许一个资源最多由几个多线程同时使用
    • 案例16
import threading
import time# 参数定义最多几个线程同时使用资源
semaphore = threading.Semaphore(3)def func():if semaphore.acquire():for i in range(5):print(threading.currentThread().getName() + ' get semaphore')time.sleep(15)semaphore.release()print(threading.currentThread().getName() + ' release semaphore')for i in range(8):t1 = threading.Thread(target=func)t1.start()

  • threading.Timer

    • 案例 17
import threading
import timedef func():print("I am running.........")time.sleep(4)print("I am done......")if __name__ == "__main__":t = threading.Timer(6, func)t.start()i = 0while True:print("{0}***************".format(i))time.sleep(3)i += 1

  • Timer是利用多线程,在指定时间后启动一个功能

  • 可重入锁

    • 一个锁,可以被一个线程多次申请
    • 主要解决递归调用的时候,需要申请锁的情况
    • 案例18
import threading
import timeclass MyThread(threading.Thread):def run(self):global numtime.sleep(1)if mutex.acquire(1):num = num+1msg = self.name+' set num to '+str(num)print(msg)mutex.acquire()mutex.release()mutex.release()num = 0mutex = threading.RLock()def testTh():for i in range(5):t = MyThread()t.start()if __name__ == '__main__':testTh()

线程替代方案

  • subprocess

    • 完全跳过线程,使用进程
    • 是派生进程的主要替代方案
    • python2.4后引入
  • multiprocessiong

    • 使用threadiing借口派生,使用子进程
    • 允许为多核或者多cpu派生进程,接口跟threading非常相似
    • python2.6
  • concurrent.futures

    • 新的异步执行模块
    • 任务级别的操作
    • python3.2后引入

多进程

  • 进程间通讯(InterprocessCommunication, IPC )
  • 进程之间无任何共享状态
  • 进程的创建
    • 直接生成Process实例对象, 案例19
import multiprocessing
from time import sleep, ctimedef clock(interval):while True:print("The time is %s" % ctime())sleep(interval)if __name__ == '__main__':p = multiprocessing.Process(target = clock, args = (5,))p.start()while True:print('sleeping.......')sleep(1)

  • 派生子类, 案例20
import multiprocessing
from time import sleep, ctimeclass ClockProcess(multiprocessing.Process):'''两个函数比较重要1. init构造函数2. run'''def __init__(self, interval):super().__init__()self.interval = intervaldef run(self):while True:print("The time is %s" % ctime())sleep(self.interval)if __name__ == '__main__':p = ClockProcess(3)p.start()while True:print('sleeping.......')sleep(1)

  • 在os中查看pid,ppid以及他们的关系

    • 案例21
from multiprocessing import Process
import osdef info(title):print(title)print('module name:', __name__)# 得到父亲进程的idprint('parent process:', os.getppid())# 得到本身进程的idprint('process id:', os.getpid())def f(name):info('function f')print('hello', name)if __name__ == '__main__':info('main line')p = Process(target=f, args=('bob',))p.start()p.join()

  • 生产者消费者模型

    • JoinableQueue
    • 案例22
import multiprocessing
from time import ctimedef consumer(input_q):print("Into consumer:", ctime())while True:# 处理项item = input_q.get()print ("pull", item, "out of q") # 此处替换为有用的工作input_q.task_done() # 发出信号通知任务完成print ("Out of consumer:", ctime()) ##此句未执行,因为q.join()收集到四个task_done()信号后,主进程启动,未等到print此句完成,程序就结束了def producer(sequence, output_q):print ("Into procuder:", ctime())for item in sequence:output_q.put(item)print ("put", item, "into q")print ("Out of procuder:", ctime())# 建立进程
if __name__ == '__main__':q = multiprocessing.JoinableQueue()# 运行消费者进程cons_p = multiprocessing.Process (target = consumer, args = (q,))cons_p.daemon = Truecons_p.start()# 生产多个项,sequence代表要发送给消费者的项序列# 在实践中,这可能是生成器的输出或通过一些其他方式生产出来sequence = [1,2,3,4]producer(sequence, q)# 等待所有项被处理q.join()

设置哨兵问题

  • 设置退出机制,使得消费者不陷入死循环

    • 采用的方式,是发送一个不可能出现的数据给joinablequeue!
  • 队列中哨兵的使用, 案例23
import multiprocessing
from time import ctime# 设置哨兵问题
def consumer(input_q):print("Into consumer:", ctime())while True:item = input_q.get()if item is None:breakprint("pull", item, "out of q")print ("Out of consumer:", ctime()) ## 此句执行完成,再转入主进程def producer(sequence, output_q):print ("Into procuder:", ctime())for item in sequence:output_q.put(item)print ("put", item, "into q")print ("Out of procuder:", ctime())if __name__ == '__main__':q = multiprocessing.Queue()cons_p = multiprocessing.Process(target = consumer, args = (q,))cons_p.start()sequence = [1,2,3,4]producer(sequence, q)q.put(None)cons_p.join()
如果有多个消费者的情况,进行哨兵的改进!
  • 哨兵的改进, 案例24
  • 设置多个哨兵!
import multiprocessing
from time import ctimedef consumer(input_q):print ("Into consumer:", ctime())while True:item = input_q.get()if item is None:breakprint("pull", item, "out of q")print ("Out of consumer:", ctime())def producer(sequence, output_q):for item in sequence:print ("Into procuder:", ctime())output_q.put(item)print ("Out of procuder:", ctime())if __name__ == '__main__':q = multiprocessing.Queue()cons_p1 = multiprocessing.Process (target = consumer, args = (q,))cons_p1.start()cons_p2 = multiprocessing.Process (target = consumer, args = (q,))cons_p2.start()sequence = [1,2,3,4]producer(sequence, q)q.put(None)q.put(None)cons_p1.join()cons_p2.join()

PYTHON 之 多线程 and 多进程相关推荐

  1. python的多线程和多进程网络编程

    二十八.python的多线程和多进程网络编程 线程和进程关系: 进程是具有独立功能的程序,进程是系统进行资源分配和调度的一个独立单位 线程是进程的一个实体,是cpu调度的基本单位,它是比进程更小的能独 ...

  2. 关于python的多线程和多进程_Python的多线程和多进程

    (1)多线程的产生并不是因为发明了多核CPU甚至现在有多个CPU+多核的硬件,也不是因为多线程CPU运行效率比单线程高.单从CPU的运行效率上考虑,单任务进程及单线程效率是最高的,因为CPU没有任何进 ...

  3. [转]Python中多线程与多进程中的数据共享问题!

    之前在写多线程与多进程的时候,因为一般情况下都是各自完成各自的任务,各个子线程或者各个子进程之前并没有太多的联系,如果需要通信的话我会使用队列或者数据库来完成,但是最近我在写一些多线程与多进程的代码时 ...

  4. Python的多线程、多进程及协程

    Python 代码执行由python虚拟机控制,每个CPU在任意时刻只有一个线程在解释器运行,对python虚拟机的访问由全局解释锁GIL控制,如在单核CPU时多线程是并发不是并行. 并发:两个或多个 ...

  5. 爬虫-python -(8) 多线程与多进程操作以及线程池 异步操作

    文章目录 1.通过异步操作提高爬虫效率 2.多线程 3.多进程 4.线程池与进程池 5.线程池实例-新发地菜价保存 6.总结 1.通过异步操作提高爬虫效率 一般爬虫过程为,请求网页-响应请求-从响应中 ...

  6. python+selenium多线程与多进程爬虫

    使用python+selenium抓取深圳证券交易所本所公告数据,刚开始是用单进程爬取的,最近将代码修改了一下,分别用多进程和多线程进行抓取,速度非常快.如果对selenium不了解的请移步别的地方学 ...

  7. python的多线程与多进程

    1.GIL(Global Interpreter Lock) 在python中,由于GIL(Global Interpreter Lock)全局解释器锁的存在,所以多线程并不是真正意义上的多线程.在 ...

  8. Python的多线程和多进程教程:大大提高效率

    一.多线程 from threading import Threaddef start(one, two):print(one, two)if __name__ == '__main__':one = ...

  9. python io密集型应用案例-Python中单线程、多线程和多进程的效率对比实验实例

    python的多进程性能要明显优于多线程,因为cpython的GIL对性能做了约束. Python是运行在解释器中的语言,查找资料知道,python中有一个全局锁(GIL),在使用多进程(Thread ...

  10. Python多线程和多进程编程

    原文地址:https://tracholar.github.io/wiki/python/python-multiprocessing-tutorial.html 简介 早已进入多核时代的计算机,怎能 ...

最新文章

  1. JavaWeb——jsp-config
  2. Flutter Web实战项目打造真正跨平台应用(windows,android,ios,linux,macos,web)
  3. 神策数据全新改版数据概览,致力打造多角色、多场景的“工作台”
  4. 【Python基础】为什么更改列表'y'也会更改列表'x'?
  5. 怎么让存储过程通用化_怎么做分布式存储的面试?
  6. 7.组件连线(贝塞尔曲线)--从零起步实现基于Html5的WEB设计器Jquery插件(含源码)...
  7. 月球好忙 蓝色起源2024年要将首位女性送上月球表面
  8. L1-067 洛希极限 (10 分)-PAT 团体程序设计天梯赛 GPLT
  9. Spring 5 新功能:函数式 Web 框架
  10. java_泛型方法使用实例
  11. bash给脚本加进度条_shell脚本进度条。
  12. 凸优化第七章统计估计 7.5实验设计
  13. cvEqualizeHist() 直方图均衡化(单通道)
  14. 读书-算法《程序设计导引及在线实践》-简单计算题1:鸡兔同笼
  15. ubuntu中非常好用的PDF软件—okular
  16. Cocos2d-x游戏引擎实战开发炸弹超人项目教程 全套下载 1至6课
  17. 计算机顶级会议Rankings 英文投稿的一点经验
  18. 移动Win7用户文件夹(我的文档)默认位置至D盘
  19. QueryDSL 关于Q类找不到的问题
  20. 七、MySQL之数据定义语言(二)

热门文章

  1. Day05_生命周期_组件进阶
  2. LDT面试:实验室开发诊断试剂监管模式(Laboratory Developed Test,LDT)
  3. Excel做数据分析?是真的很强
  4. 怎么设置计算机桌面一键关机,图文详解如何设置电脑定时开关机
  5. vue项目实现高德地图截图
  6. 操作系统 实时调度
  7. NFC源码分析之P2P工作模式.
  8. 微软商店无法连接网络的问题解决
  9. ios WKWebView之视频无法播放
  10. 手机app怎么制作?app软件开发流程详解