那曲檬骨新材料有限公司

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內(nèi)不再提示

Python-多線程、多進程、協(xié)程

汽車電子技術 ? 來源:程序猿知秋 ? 作者:程序猿知秋 ? 2023-02-16 15:46 ? 次閱讀

基本使用

**基本概念

**

  • 進程
    • 幾乎所有的操作系統(tǒng)都支持同時運行多個任務,一個任務通常就是一個程序,每個運行中的程序就是一個進程
    • 進程是處于運行過程中的程序,并且具有一定的獨立功能
    • 進程是系統(tǒng)進行資源分配調(diào)度的一個獨立單位
  • 線程
    • 線程(Thread)也叫 輕量級進程 ,是操作系統(tǒng)能夠進行運算調(diào)度的最小單位
    • 它被包涵在進程之中,是進程中的實際運作單位,線程自己不擁有系統(tǒng)資源,只擁有一點兒在運行中必不可少的資源,但它可與同屬一個進程的其它線程共享進程所擁有的全部資源
    • 進程中的多個線程之間可以并發(fā)執(zhí)行

一個進程可以擁有多個線程,一個線程必須有一個父進程。線程可以擁有自己的堆棧、自己的程序計數(shù)器和自己的局部變量,但不擁有系統(tǒng)資源,它與父進程的其他線程共享該進程所擁有的全部資源。

多線程的優(yōu)點

  • 進程之間不能共享內(nèi)存,但線程之間共享內(nèi)存非常容易
  • 操作系統(tǒng)在創(chuàng)建進程時,需要為該進程重新分配系統(tǒng)資源,但創(chuàng)建線程的代價則小得多。因此,使用多線程來實現(xiàn)多任務并發(fā)執(zhí)行比使用多進程的效率高
  • Python 語言內(nèi)置了多線程功能支持,而不是單純地作為底層操作系統(tǒng)的調(diào)度方式,從而簡化了 Python 的多線程編程

示例

**方式一: **使用 threading.Thread(target=方法名) 的方式實現(xiàn)多線程

參數(shù)說明:threading.Thread(參數(shù)說明)

  • target: 指定該線程要調(diào)度的目標方法。只傳函數(shù)名,不傳函數(shù),即不加()
  • args: 指定一個元組,以位置參數(shù)的形式為target指定的函數(shù)傳入?yún)?shù)。元組的第一個參數(shù)傳給target的第一個,以此類推
  • kwargs: 指定一個字典,以關鍵字參數(shù)的形式為target指定的函數(shù)傳入?yún)?shù)
  • daemon:指定所構建的線程是否為后臺線程
import time
import threading




def eat(num):
    for i in range(num):
        print("我正在吃飯......")
        time.sleep(1)




def drunk(num=10):
    for i in range(num):
        print("我正在喝水......")
        time.sleep(1)




if __name__ == '__main__':
    # 創(chuàng)建兩個線程
    t1 = threading.Thread(target=eat, args=(10,))
    t2 = threading.Thread(target=drunk)
    # 啟動兩個線程
    t1.start()
    t2.start()


    while True:
        threadList = threading.enumerate()
        print("正在運行的線程是:", threadList)
        print("正在運行的線程數(shù)量是:", len(threadList))
        time.sleep(2)

方式二: 繼承threading.Thread

import time
import threading




class MyThread(threading.Thread):


    def run(self):
        for i in range(10):
            print("線程啟動了,我的名字叫:", self.name)
            time.sleep(1)




if __name__ == '__main__':
    # 創(chuàng)建兩個線程
    t1 = MyThread()
    t2 = MyThread()
    # 啟動兩個線程, start() 方法內(nèi)部會自動去調(diào)用 run方法,所以此處寫 start() 就可以了
    t1.start()
    t2.start()


    while True:
        threadList = threading.enumerate()
        print("正在運行的線程是:", threadList)
        print("正在運行的線程數(shù)量是:", len(threadList))
        time.sleep(2)

全局變量、互斥鎖、死鎖

共享全局變量示例

import threading


g_num = 0


def fun_1(num):
    global g_num
    for i in range(num):
        g_num += 1
    print("------fun_1的g_num值:%d" % g_num)




def fun_2(num):
    global g_num
    for i in range(num):
        g_num += 1
    print("------fun_2的g_num值:%d" % g_num)




if __name__ == '__main__':
    t1 = threading.Thread(target=fun_1, args=(1000000,))
    t2 = threading.Thread(target=fun_2, args=(1000000,))
    t1.start()
    t2.start()

輸出結果 :

圖片

從以上結果可以看出,直接使用全局變量是有問題的,按理說,預期結果應該是2000000,實際結果相關很大,且每次執(zhí)行結果都不一樣

原因

  • 在g_num=0 時,t1取得g_num=0,此時系統(tǒng)把t1調(diào)度為 "sleeping" 狀態(tài),把t2轉換為 "running" 狀態(tài),t2 這時也獲得了 g_num=0
  • 然后 t2對得到的值進行加1,并賦給g_num,使得g_num=1
  • 然后系統(tǒng)又把 t2調(diào)度為"sleeing",把t1轉為"running",線程t1又把它之前得到的0 加1后賦值給 g_num。
  • 這樣就導致了 t1和t2都對 g_num加1,但結果仍然是 g_num=1

解決方案:互斥鎖

  • 當多個線程幾乎同時修改某個共享數(shù)據(jù)的時候,需要進行同步控制
  • 某個線程要更改共享數(shù)據(jù)時,先將其鎖定,此時資源狀態(tài)為**” 鎖定 ,其他線程不能更改;直到該線程釋放資源,將資源的狀態(tài)改為 ”**非鎖定 “, 其他的線程才能再次鎖定該資源。互拆鎖保證了 每次只有一個線程進行寫入操作 ,從而保證了多線程數(shù)據(jù)的正確性
import threading


g_num = 0


def fun_1(num):
    global g_num
    for i in range(num):
        # 上鎖,如果之前沒上鎖,此時調(diào)用就會上鎖;如果之前上鎖了,此時調(diào)用就會阻塞,直接鎖被別人釋放
        lock.acquire()
        g_num += 1
        # 釋放鎖
        lock.release()
    print("------fun_1的g_num值:%d" % g_num)




def fun_2(num):
    global g_num
    for i in range(num):
        # 上鎖,如果之前沒上鎖,此時調(diào)用就會上鎖;如果之前上鎖了,此時調(diào)用就會阻塞,直接鎖被別人釋放
        lock.acquire()
        g_num += 1
        # 釋放鎖
        lock.release()
    print("------fun_2的g_num值:%d" % g_num)




if __name__ == '__main__':
    # 創(chuàng)建一個互斥鎖,默認是沒上鎖的
    lock=threading.Lock()


    t1 = threading.Thread(target=fun_1, args=(1000000,))
    t2 = threading.Thread(target=fun_2, args=(1000000,))
    t1.start()
    t2.start()

死鎖

  • 在線程共享多個資源的時候,如果兩個線程分別占有一部分資源并且同時等待對方的資源,就會造成死鎖
  • 盡管死鎖很少發(fā)生,但一旦發(fā)生就會造成程序停止響應
import threading
import time




def fun_1():
    # 1號鎖,上鎖
    lock1.acquire()
    print("fun_1..do some thing.........1")
    time.sleep(1)


    # 2號鎖,上鎖,如果被別人占用了,則會阻塞
    lock2.acquire()
    print("fun_1..do some thing..........2")
    # 釋放2號鎖
    lock2.release()


    # 釋放1號鎖
    lock1.release()




def fun_2():
    # 2號鎖,上鎖
    lock2.acquire()
    print("fun_2..do some thing.........2")
    time.sleep(1)


    # 1號鎖,上鎖,如果被別人占用了,則會阻塞
    lock1.acquire()
    print("fun_2..do some thing..........1")
    # 釋放1號鎖
    lock1.release()


    # 釋放2號鎖
    lock2.release()


if __name__ == '__main__':
    # 創(chuàng)建兩個互斥鎖
    lock1=threading.Lock()
    lock2=threading.Lock()


    t1 = threading.Thread(target=fun_1)
    t2 = threading.Thread(target=fun_2)
    t1.start()
    t2.start()

輸出結果:會一直停止阻塞

圖片

死鎖解決方案

  • 程序設計時避免

  • **添加超時等待

    **

進程

進程的狀態(tài)

  • 新建:操作系統(tǒng)調(diào)度啟動一個新進程
  • 就緒態(tài):運行的條件都已經(jīng)滿足,等待cpu執(zhí)行
  • 執(zhí)行態(tài):cpu 正在執(zhí)行
  • 等待態(tài):等待某些條件滿足,例如一個程序sleep了,此時就處于等待態(tài)

圖片

進程的創(chuàng)建

  • 在python中,提供了 multiprocessing 模塊,就是跨平臺的多進程模塊,模塊提供了 Process類來代表一人進程對象,這個對象可以理解為一個獨立的進程
  • Process 參數(shù)說明
    • target:傳遞函數(shù)的引用,子進程將執(zhí)行這個函數(shù)
    • args:給target指定的函數(shù),傳遞參數(shù),以元組的方式傳遞,非必填
    • kwargs:給target指定的函數(shù)傳遞命名參數(shù),非必填
    • name:給進程設定一個名稱,非必填
    • group:指定進程組,非必填
  • Process 對象的常用方法
    • start():啟動子進程
    • is_alive():判斷子進程是否還活著
    • join(timeout):是否等待子進程執(zhí)行結束,或等待多少秒
    • terminate():不管任務是否完成,立即終止子進程
  • Process 對象的常用屬性
    • name:當前進程的別名,默認為Process-x, x為從1開始遞增的整數(shù)
    • pid:當前進程的pid (進程號)

示例

import time
import os
import multiprocessing




def eat(num):
    for i in range(num):
        print("我正在吃飯......,我的進程號是:%d,父進程的進程號是:%d" % (os.getpid(),os.getppid()))
        time.sleep(1)




def drunk(num):
    for i in range(num):
        print("我正在喝水......我的進程號是:%d,父進程的進程號是:%d" % (os.getpid(),os.getppid()))
        time.sleep(1)




if __name__ == '__main__':
    # 創(chuàng)建兩個進程
    p1 = multiprocessing.Process(target=eat, args=(10,))
    p2 = multiprocessing.Process(target=drunk, args=(10,))
    # 啟動兩個進程
    p1.start()
    p2.start()


    print("主進程的進程號是:%d" %os.getpid())

輸出結果

圖片

進程線程區(qū)別

  • 功能區(qū)別
    • 進程:能夠完成多任務,比如,在一臺電腦上運行多個qq
    • 線程:能夠完成多任務,比如,在一個qq中開多個聊天窗口
  • 調(diào)度
    • 進程是資源分配的基本單位
    • 線程是cpu調(diào)度和執(zhí)行的最小單位
  • 擁有資源
    • 進程擁有資源的一個獨立單位
    • 線程不擁有系統(tǒng)資源,但可以訪問隸屬于進程的資源
  • 穩(wěn)定性
  • 進程有獨立的地址空間,多進程較穩(wěn)定,因為其中一個出現(xiàn)狀況不影 響另外一個

  • 同一個進程的多個線程,共用地址空間,多線程相比于多進程,穩(wěn)定性要差,因為一個線程出現(xiàn)問題會嚴重影響其他線程

  • 依賴關系
    • 一個線程只能屬性一個進程
    • 一個進程至少有一個線程
  • 針對全局變量的共享
    • 多進程間不共享全局變量(進程間都是獨立的)
    • 多線程間共享全局變量

進程間的通信

  • 不同的進程間有時也需要進行數(shù)據(jù)傳遞,在Python中,可以使用 muitiprocessiong模塊的 Queue ,來實現(xiàn)進程間的數(shù)據(jù)傳遞
  • Queue 是一個消息隊列,數(shù)據(jù)是先進先出的原則

示例

import time
import multiprocessing




def set_data(queue):
    numList=[1,2,3,4]
    for i in numList:
        # 給隊列中放數(shù)據(jù),如果隊列已經(jīng)滿了,則會阻塞,直到能放數(shù)據(jù)為止
        queue.put(i)


    time.sleep(1)




def get_data(queue):
    while True:
        # 判斷隊列中如果沒有數(shù)據(jù)了,則退出循環(huán)
        if queue.empty():
            break


        # 從隊列中取數(shù)據(jù)
        data=queue.get()
        print("從隊列中取出的數(shù)據(jù)是:",data)


if __name__ == '__main__':
    # 創(chuàng)建一個消息列表,容量是3(表示只能裝3個數(shù)據(jù))
    queue=multiprocessing.Queue(3)


    # 創(chuàng)建兩個進程
    p1 = multiprocessing.Process(target=set_data, args=(queue,))
    p2 = multiprocessing.Process(target=get_data, args=(queue,))
    # 啟動兩個進程
    p1.start()
    p2.start()

**輸出結果 **

圖片

進程池

  • 需要創(chuàng)建成百上千個進程時,可以使用 muitiprocessing模塊提供的 Pool 方法
  • 初始化Pool時 ,可以指定一個最大進程數(shù),當有新的請求提交到Pool中時,如果池里面沒有滿,就會創(chuàng)建一個新的進程來執(zhí)行該請求,如果已經(jīng)滿了,那么就會等待,直到池中有空閑進程,會調(diào)用空閑進程來執(zhí)行新任務

示例

import time
import os
import multiprocessing


def work(msg):
    print("開始執(zhí)行工作,當前進程是:",os.getpid())
    time.sleep(2)
    print("接收到的消息數(shù)據(jù)是:%s"%msg)




if __name__ == '__main__':
    # 創(chuàng)建進程池,容量為3
    pool=multiprocessing.Pool(3)


    for i in range(10):
        # pool.apply_async(要調(diào)用的目標,(傳遞給目標的參數(shù)元組,))
        # 每次循環(huán)將會用空閑的子進程去執(zhí)行任務
        pool.apply_async(work,("傳遞參數(shù):%d"%i,))


    # 關閉進程池,關閉后進程池不再接收新請求
    pool.close()
    # 等待進程池中所有的子進程執(zhí)行完成 ,必須放在close 語句之后
    pool.join()

輸出結果

圖片

協(xié)程

迭代器

  • 迭代是訪問集合元素的一種方式
  • 迭代器是一個可以記住遍歷位置的對象。
  • 迭代器對象從集合的第一個元素開始訪問,直到所有的元素都訪問完成
  • 迭代器只會前進,不會后退
  • 我們把對 list、set、str、tuple 等類型的數(shù)據(jù)使用 for...in ... 的方式從中獲取數(shù)據(jù),這樣的過程稱為 遍歷(循環(huán))也叫迭代

判斷一個數(shù)據(jù)類型是否可迭代,使用 isinstance(xxx,Iterable)

from collections.abc import Iterable


list1=[1,2]
str1="123"
tuple1=(1,2)
dict1={1:"a",2:"b"}
num=122


print(isinstance(list1,Iterable))
print(isinstance(str1,Iterable))
print(isinstance(tuple1,Iterable))
print(isinstance(dict1,Iterable))
print(isinstance(num,Iterable))

輸出結果

圖片

自已實現(xiàn)迭代器示例

class MyIterator:
    """自己實現(xiàn)一個迭代器"""


    def __init__(self):
        self.name = list()
        self.currentIndex = 0


    def add(self, arg):
        self.name.append(arg)


    def __iter__(self):
        # 如果想要一個對象成為可以被迭代的對象,即可以使用 for ... in ... ,那么必須實現(xiàn) __iter__ 方法
        return self


    def __len__(self):
        return len(self.name)


    def __next__(self):
        # 當使用for...in... 迭代時,會先調(diào)用 __iter__ 方法,然后調(diào)用其返回對象中的 __next__ 方法(即本方法)
        if self.currentIndex < len(self.name):
            result = self.name[self.currentIndex]
            self.currentIndex += 1
            return result
        else:
            # 拋出一個 停止迭代的異常
            raise StopIteration




myIter = MyIterator()
myIter.add("張三")
myIter.add("李四")
myIter.add("王五")


for i in myIter:
    print(i)


# 獲取集合長度
print(len(myIter))

**生成器

**

  • 生成器是一種特殊的迭代器
  • 創(chuàng)建生成器有兩種方式
    • 方式一:把一個列表生成式的[] 改成 ()
    • # 原始列表
      l=[x*2 for x in range(10)]
      # 構建生成器
      g=(x*2 for x in range(10))
      
      
      # 迭代創(chuàng)建的生成器
      for i in g:
          print(i)
      
  • 方式二:使用 yield 關鍵字
  • def create_age(num):
        currentAge=0
        while currentAge# 創(chuàng)建生成器中的 值,并打印 send 過來的參數(shù)值
            sendMsg=yield currentAge
            print("%s 的年齡是:%d"%(sendMsg,currentAge))
            currentAge+=1
    # 創(chuàng)建生成器,并初始化10個值
    obj=create_age(10)
    
    
    # 迭代一次 生成器中的值
    n=next(obj)
    ss=obj.send("name"+str(0))
    print("send的結果:",ss)
    
    
    # 迭代后續(xù),生成器中的值
    for i in obj:
        print(i)
    

協(xié)程

  • 實現(xiàn)方式一:采用yield 實現(xiàn)
import time


def eat():
    while True:
        print("我在吃飯.....")
        time.sleep(1)
        yield




def drunk():
    while True:
        print("我在喝水.....")
        time.sleep(1)
        yield


if __name__ == '__main__':
    # 創(chuàng)建兩個生成器
    eat=eat()
    drunk=drunk()


    while True:
        next(eat)
        next(drunk)
  • 實現(xiàn)方式二:采用 greenlet 實現(xiàn)
    • 先安裝 greenlet 模塊:pip install greenlet
import time
from greenlet import greenlet




def eat():
    while True:
        print("我在吃飯.....")
        # 切換到g2中運行
        g2.switch()
        time.sleep(1)




def drunk():
    while True:
        print("我在喝水.....")
        # 切換到g1中運行
        g1.switch()
        time.sleep(1)




if __name__ == '__main__':
    # 創(chuàng)建兩個生成器
    g1 = greenlet(eat)
    g2 = greenlet(drunk)


    # 切換到g1中運行
    g1.switch()
  • 實現(xiàn)方式三:采用 gevent實現(xiàn) 推薦使用
    • 由于 greenlet 需要人手動切換,比較占用IO資源,并且會出現(xiàn),一旦中間某個程序處于線程等待的話,會一直等待很長時間的問題。所以gevent就應運而生,gevent 遇到延時阻塞會自動切換
    • 先安裝 gevent模塊:pip install gevent
import time
import gevent
from gevent import monkey


# 有耗時操作時需要, 將程序中用到的耗時操作的代碼,換為gevent中自己實現(xiàn)的模塊
monkey.patch_all()




def work(num):
    for i in range(num):
        print(gevent.getcurrent(), i)
        # 使用 mokey.patch_all() 之后,程序會自動替換成 gevent里面的 gevent.sleep() 方法
        time.sleep(1)




if __name__ == '__main__':
    # 創(chuàng)建并啟動協(xié)程
    gevent.joinall({
        gevent.spawn(work, 10),
        gevent.spawn(work, 10)
    })

圖片下載器實現(xiàn)

import gevent
from gevent import monkey
from urllib import request


# 有耗時操作時需要, 將程序中用到的耗時操作的代碼,換為gevent中自己實現(xiàn)的模塊
monkey.patch_all()


def down_pic(filename,url):
    resp=request.urlopen(url)
    data=resp.read()


    # 寫入文件
    with open(filename,"wb") as f:
        f.write(data)




if __name__ == '__main__':
    # 創(chuàng)建并啟動協(xié)程
    gevent.joinall({
        gevent.spawn(down_pic, "1.jpg","https://himg3.qunarzz.com/imgs/201812/14/C._M0DCiiigrWCy4LQi1024.jpg"),
        gevent.spawn(down_pic, "2.jpg","https://source.qunarzz.com/site/images/zhuanti/huodong/shangwu.jpg")
    })

總結

  • 進程是資源分配的單位
  • 線程是操作系統(tǒng)調(diào)度的單位
  • 進程切換需要的資源最大,效率很低
  • 線程切換需要的資源一般,效率一般(不考慮GIL的情況下)
  • 協(xié)程切換任務資源很小,效率高
  • 多進程、多線程根據(jù)cpu核數(shù)不一樣可能是并行的,但是協(xié)程是在一個線程中,所以是并發(fā)
聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權轉載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內(nèi)容侵權或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 操作系統(tǒng)

    關注

    37

    文章

    6895

    瀏覽量

    123745
  • 程序
    +關注

    關注

    117

    文章

    3795

    瀏覽量

    81411
  • 任務
    +關注

    關注

    1

    文章

    20

    瀏覽量

    8561
  • 進程
    +關注

    關注

    0

    文章

    204

    瀏覽量

    13995
收藏 人收藏

    評論

    相關推薦

    多線程多進程的區(qū)別

    6.你的數(shù)據(jù)庫一會又500個連接數(shù),一會有10個,你分析一下情況7.udp和tcp的區(qū)別8.多線程多進程的區(qū)別9.有一臺web服務器,你選擇用多線程還是多進程,...
    發(fā)表于 07-19 07:21

    淺談多進程多線程的選擇

    魚還是熊掌:淺談多進程多線程的選擇關于多進程多線程,教科書上最經(jīng)典的一句話是“進程是資源分配的最小單位,
    發(fā)表于 08-24 07:38

    協(xié)線程有什么區(qū)別

    協(xié)線程的區(qū)別協(xié)線程的共同目的之一是實現(xiàn)系統(tǒng)資源的上下文調(diào)用,不過它們的實現(xiàn)層級不同;
    發(fā)表于 12-10 06:23

    python多線程多進程對比

    段可以干多件事,譬如可以邊吃飯邊看電視;在Python中,多線程協(xié) 雖然是嚴格上來說是串行,但卻比一般的串行程序執(zhí)行效率高得很。 一般的串行程序,在程序阻塞的時候,只能干等著,
    發(fā)表于 03-15 16:42

    LINUX系統(tǒng)下多線程多進程性能分析

    采用多進程處理多個任務,會占用很多系統(tǒng)資源(主要是CPU 和內(nèi)存的使用)。在LINUX 中,則對這種弊端進行了改進,在用戶態(tài)實現(xiàn)了多線程處理多任務。本文系統(tǒng)論述了多線程
    發(fā)表于 08-13 08:31 ?20次下載

    如何選好多線程多進程

    關于多進程多線程,教科書上最經(jīng)典的一句話是“進程是資源分配的最小單位,線程是CPU調(diào)度的最小單位”,這句話應付考試基本上夠了,但如果在工作中遇到類似的選擇問題,那就沒有這么簡單了,選
    的頭像 發(fā)表于 05-11 16:16 ?3016次閱讀
    如何選好<b class='flag-5'>多線程</b>和<b class='flag-5'>多進程</b>

    多進程多線程的深度比較

    嵌入式Linux中文站,關于多進程多線程,教科書上最經(jīng)典的一句話是“進程是資源分配的最小單位,線程是CPU調(diào)度的最小單位”。這句話應付考試基本上夠了,但如果在工作中遇
    發(fā)表于 04-02 14:42 ?502次閱讀

    Python后端項目的協(xié)是什么

    最近公司 Python 后端項目進行重構,整個后端邏輯基本都變更為采用“異步”協(xié)的方式實現(xiàn)。看著滿屏幕經(jīng)過 async await(協(xié)
    的頭像 發(fā)表于 09-23 14:38 ?1368次閱讀

    python多線程多進程的對比

    在同一時間段可以干多件事,譬如可以邊吃飯邊看電視; 在Python中, 多線程協(xié) 雖然是嚴格上來說是串行,但卻比一般的串行程序執(zhí)行效率高得很。 一般的串行程序,在程序阻塞的時候
    的頭像 發(fā)表于 03-15 16:42 ?2039次閱讀
    <b class='flag-5'>python</b><b class='flag-5'>多線程</b>和<b class='flag-5'>多進程</b>的對比

    Python多進程學習

    Python 多進程 (Multiprocessing) 是一種同時利用計算機多個處理器核心 (CPU cores) 進行并行處理的技術,它與 Python多線程 (Multith
    的頭像 發(fā)表于 04-26 11:04 ?602次閱讀

    淺談Linux網(wǎng)絡編程中的多進程多線程

    在Linux網(wǎng)絡編程中,我們應該見過很多網(wǎng)絡框架或者server,有多進程的處理方式,也有多線程處理方式,孰好孰壞并沒有可比性,首先選擇多進程還是多線程我們需要考慮業(yè)務場景,其次結合當
    發(fā)表于 08-08 16:56 ?856次閱讀
    淺談Linux網(wǎng)絡編程中的<b class='flag-5'>多進程</b>和<b class='flag-5'>多線程</b>

    關于Python多進程多線程詳解

    進程(process)和線程(thread)是操作系統(tǒng)的基本概念,但是它們比較抽象,不容易掌握。關于多進程多線程,教科書上最經(jīng)典的一句話是“進程
    的頭像 發(fā)表于 11-06 14:46 ?906次閱讀
    關于<b class='flag-5'>Python</b><b class='flag-5'>多進程</b>和<b class='flag-5'>多線程</b>詳解

    Linux系統(tǒng)上多線程多進程的運行效率

    關于多進程多線程,教科書上最經(jīng)典的一句話是“進程是資源分配的最小單位,線程是CPU調(diào)度的最小單位”,這句話應付考試基本上夠了,但如果在工作中遇到類似的選擇問題,那就沒有這么簡單了,選
    的頭像 發(fā)表于 11-10 10:54 ?1473次閱讀
    Linux系統(tǒng)上<b class='flag-5'>多線程</b>和<b class='flag-5'>多進程</b>的運行效率

    你還是分不清多進程多線程嗎?一文搞懂!

    你還是分不清多進程多線程嗎?一文搞懂! 多進程多線程是并發(fā)編程中常見的兩個概念,它們都可以用于提高程序的性能和效率。但是它們的實現(xiàn)方式和使用場景略有不同。 1.
    的頭像 發(fā)表于 12-19 16:07 ?622次閱讀

    Python多線程多進程的區(qū)別

    Python作為一種高級編程語言,提供了多種并發(fā)編程的方式,其中多線程多進程是最常見的兩種方式之一。在本文中,我們將探討Python多線程
    的頭像 發(fā)表于 10-23 11:48 ?494次閱讀
    <b class='flag-5'>Python</b>中<b class='flag-5'>多線程</b>和<b class='flag-5'>多進程</b>的區(qū)別
    威尼斯人娱乐城线路| 百家乐官网三多注码法| 百家乐官网庄闲和各是多少| 澳门百家乐奥秘| E乐博百家乐| 澳门百家乐官网博| 波克棋牌斗地主| 太子百家乐官网娱乐城| 大发888博彩官方下载| 黄梅县| 百家乐视频游戏掉线| 宝龙国际娱乐城| 澳门百家乐娱乐城送彩金| 九寨沟县| 南京百家乐菜籽油| 百家乐官网娱乐城介绍| 百家乐怎赌才赢钱| 澳门百家乐官网真人娱乐城| 蓝盾百家乐的玩法技巧和规则 | 金博士百家乐官网娱乐城| 全讯网ra1777| 新濠峰百家乐官网的玩法技巧和规则 | 太阳城线上真人娱乐| 百家乐官网赌博代理| 大发888真钱官网| 百家乐官网园蒙特卡罗| 在线棋牌游戏| 澳门百家乐官网娱乐城怎么样| 威尼斯人娱乐城会员| 新锦江百家乐官网的玩法技巧和规则 | 百家乐网上娱乐场开户注册| 百家乐官网智能分析| 大发888娱乐场下载远程| 百家乐经验之谈| 百家乐官网论坛白菜| 战神百家乐的玩法技巧和规则 | 中国德州扑克比赛| 百家乐投注方法投资法| 博彩百家乐官网软件| 大发888游戏平台 17| 百家乐游戏机子|