日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

python进程线程协程区别_Python3多线程与协程

發布時間:2025/4/16 python 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python进程线程协程区别_Python3多线程与协程 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

python中的多線程非常的常用,之前一直糊里糊涂地使用,沒有一些系統性的概念,記錄一下~

0x001 多線程的優勢:可將長時間占用的程序放到后臺

可能會加速程序執行速度

能夠實現一些類似同步執行的效果

0x002 線程線程是OS的執行單元

每個獨立的線程都有一個程序運行的入口、順序執行序列和程序出口,線程不能離開程序獨立執行。

每個線程都有自己唯一的一組CPU寄存器(上下文),反映了線程上次運行時該CPU寄存器的狀態。線程中指令指針和堆棧指針寄存器非常重要,線程在進程中得到上下文,這些地址用于標志擁有線程的進程地址空間中的內存

線程可被搶占

線程退讓

0x01 分類:名字

說明

用戶線程

不需內核支持而在用戶程序中實現的線程

內核線程

操作系統內核創建和撤銷

0x02 Py3中的threading模塊:方法

說明

threading.current_thread()

返回當前的線程變量

threading.enumerate()

返回正在運行線程的list(啟動后,結束前)

threading.active_count

等于len(threading.enumerate())

提供了 Thread類,所以還可以

方法

說明

run()

表示線程活動的方法

start()

啟動線程活動

join([time])

阻塞式等待線程終止

isAlive()

線程是否活動

getName()

返回線程名

setName()

設置線程名

# -*- coding:utf-8 -*-

# 多線程

# DYBOY

# time:2019-3-10 09:37:48

import threading

import time

def printNum(endNum):

for i in range(1,endNum+1):

print(i, time.time())

# 創建線程

t = threading.Thread(target=printNum, name='printThread', args=(10,))

t.start()

t.join()

print("線程%s結束" % threading.current_thread().name)

0x003 多線程&多進程&線程鎖多進程中同一變量,各自有拷貝到自己的進程中,互不影響,多線程中,變量由多個線程共享,因此多線程中變量的同步就需要的到控制

lock = threading.Lock()

def runThread():

for i in range(1000):

lock.acquire()

try:

#....執行函數

finally:

lock.release()

# -*- coding:utf-8 -*-

# 多線程

# DYBOY

# time:2019-3-10 09:37:48

import threading

import time

money = 0

lock = threading.Lock()

def chaneMoney(num):

global money

money += num

money -= num

def runThread(n):

for i in range(1000):

lock.acquire()

try:

chaneMoney(n)

finally:

lock.release()

t1 = threading.Thread(target=runThread, args=(100,))

t2 = threading.Thread(target=runThread, args=(50,))

t1.start()

t2.start()

t1.join()

t2.join()

print("余額:",money)

ps: 在實際的運行中,發現似乎線程鎖沒有起到作用,在線程中的join() 方法似乎是有影響的,

join():阻塞當前進程/線程,直到調用join方法的那個進程執行完,再繼續執行當前進程。相當于線程守護,直到調用join()方法的線程執行完畢,才將控制權交給主進程。

0x04 問題?

從上,看到多線程中為了保證數據的一致性,使用了線程鎖來實現類似同步的功能,然而這樣反而多了獲取鎖和釋放鎖的步驟,所以在我看來。線程也沒有加快程序的運行時間。

一個程序從執行到結束,首先會創建一個主進程,os的執行單元是線程,一個進程有至少一個或多個線程來實現其功能,在線程的創建和上下文切換是一個比較大的開銷,提升多線程的優勢就需要從其中來考慮:

無鎖并發(減少數據關聯度,更合理優化的實現方式)

減少并發(線程不能無限制的多)

減少上下文切換的開銷(協程)

0x05 協程函數調用的時候,是使用棧的方式,比如A調用B,B調用C,C執行返回給B,B執行完后返回給A,是一個壓棧出棧的過程

子程序(函數),總是一個入口,一次返回,調用的順序永遠如此,所以如果有比較頻繁的函數調用,那么就用較多的上下文切換時間,利用協程(微線程)可以較好解決這個問題。

協程是一個線程執行,那怎么利用多核CPU呢?最簡單的方法是多進程+協程,既充分利用多核,又充分發揮協程的高效率,可獲得極高的性能。(多進程)

# -*- coding:utf-8 -*-

# 協程 gevent

# DYBOY

# time:2019-3-10 09:37:48

# description: 下載圖片到本地(普通版本)

# from gevent import monkey

# monkey.patch_all()

import requests,time,json

def get_save_pic(picUrl, name):

img = requests.get(picUrl)

with open('pic/'+name,'wb') as f:

f.write(img.content)

return None

if __name__ == '__main__':

sT = time.time()

jsonData = requests.get('http://img.top15.cn/piclist.php')

jsonData = json.loads(jsonData.text)

imgs = jsonData['data']

for img in imgs:

get_save_pic(img[0], img[1])

print("Success", time.time() - sT)

網絡效果好的時候:

# -*- coding:utf-8 -*-

# 協程 gevent

# DYBOY

# time:2019-3-10 09:37:48

# description: 下載圖片到本地

from gevent import monkey

monkey.patch_all()

import gevent,requests,time,json

def get_save_pic(picUrl, name):

img = requests.get(picUrl)

with open('pic/'+name,'wb') as f:

f.write(img.content)

return None

if __name__ == '__main__':

startTime = time.time()

jsonData = requests.get('http://img.top15.cn/piclist.php')

jsonData = json.loads(jsonData.text)

imgs = jsonData['data']

targetLists = []

for img in imgs:

targetLists.append(gevent.spawn(get_save_pic, img[0], img[1]))

gevent.joinall(targetLists)

print("Success!", time.time()-startTime)

# 不知道什么原因,沒有輸出,但是從執行的結果上來看

# 最后,所有圖片同時在文件夾生成,非常迅速

2019-3-10 22:05:04 在命令行下可正常執行!

從肉眼可見的角度來看,還是協程的效果更好(在數據量不大下,感覺比較而得出的結論還是不是很有說服力,在數據量大的情況下,線程不能無限增加,協程的效果表現更優異,再加上多進程應該就更NICE了)。

0x06 總結

本次探究的是多線程與協程的區別,多線程不能無限創建,所以有的時候創建多線程在生產環境下是不可行的,在爬蟲下載圖片這部分是可以使用多線程去下載,多線程其實也是一個等待執行的過程,其與協程的差別主要是在上下文切換上,協程減少了上下文切換的時間,是程序自己控制的,而多線程的上下文切換是需要系統調用會耗費更多的時間,本次例子實現中使用了monkey這個模塊,還不清楚其中遇到的輸出問題,繼續探究!

總結

以上是生活随笔為你收集整理的python进程线程协程区别_Python3多线程与协程的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。