7.21進程線程學習總結

今天學了進程線程一些知識
自我總結。

1.進程:在爲引入線程之前,是資源調度分配的基本單位(從操作系統中得來)
2.線程:是cpu調度分配資源的基本單位

特點:進程之間是互相不影響的,不能訪問彼此的資源,其中一個進程裏面有多個線程,線程之間可以互相訪問彼此的資源,切有一個父線程和多個子線程。

說說線程:
線程的基本調用方式要會使用,
其中有一個join()方法等同於wait()方法,是指該線程運行完了纔會繼續下面的操作。
而我們的創建守護線程的方法t.setDaemon()=True,必須是在線程開始運行之前設置,他在主線程結束後自動結束.
mutex互斥鎖,遞歸鎖的一些介紹
信號量的引用:
是相當於給定一定空間資源給線程,讓他們最多能同時運行n個,

import threading,time
def run(n):
    semp.acquire()#申明一個信號量
    time.sleep(2)
    print('run the thread %s\n'%n)
    semp.release()#釋放一個信號量
if __name__ == '__main__':
    semp=threading.BoundedSemaphore(5)#創建5個信號量
    for i in range(20):
        t=threading.Thread(target=run,args=(i,))
        t.start()
while threading.active_count()!=1:
    pass
else:
    print('the thread done!')

event事件:
創建一個Event對象,然後他會有兩中狀態,set(),clear(),設置和清除設置。
我個人是這樣理解的:類似於操作系統中的阻塞,就緒,和執行,此處跟着做了一個交通燈小實驗

#創建一個event事件,wait()函數相當等待事件set(),否則不運行,當我們使用set()函數之後
#可以使用clear()清除設置,有點類似於阻塞,等待,和執行
#在這裏我們創建一個小汽車等紅綠燈模型
import  threading,time
et=threading.Event()
#紅綠燈進程
def light():
    count=1 #計算時間的變量
    et.set()#初始設置
    while True:
        if count<6:
            print('\033[42;1m the green light!\033[0m')
        elif count>=6 and count<=10:
            et.clear()
            print('\033[41;1m the red light!\033[0m')
        else:
            et.set()
            count=1#時間重置
        time.sleep(1)
        count+=1

lg=threading.Thread(target=light)
lg.start()
#創建一個車的進程
def car(name):
    while True:
        if et.is_set():#判斷事件是否被設置
            print('%s is running now!!!'%name)
            time.sleep(1)
        else:
            print('%s is stop now!!!'%name)
            et.wait()#若紅燈結束,事件被設置在這一直等待
            print('\033[32;1m green light is start! gogogo\033[0m')
ca=threading.Thread(target=car,args=('Tasla',))
ca.start()

結果如下:
在這裏插入圖片描述
在後面就是使用隊列簡述簡單的消費者生產者問題:
我們這裏引入的隊列是可以稱爲線程隊列(我自己的看法和總結)

# -*- coding: utf-8 -*-
#Author :The Y Devil
#創建一個隊列來模擬緩衝池
#生產者與消費者共同使用進程來併發執行

import threading,time,queue

q=queue.Queue()

def Producer(name):
    count=1
    while True:
        q.put("第%s骨頭"%count)#把東西放入隊列
        print('%s 生成了%s個骨頭\n'%(name,count))
        count+=1
        time.sleep(0.4)
def Customer(name):
    while True:
        print('%s 取到了 %s ,並喫掉了他\n'%(name,q.get()))#當get沒有或得值時候會繼續等待,
        time.sleep(1)
p=threading.Thread(target=Producer,args=('付,))
p.start()
c=threading.Thread(target=Customer,args=('梁偉',))
c.start()
c1=threading.Thread(target=Customer,args=('皮皮蝦',))
c1.start()

以上大致是今天學習的線程總結

進程

進程可以創建子進程:
子進程除了與父進程代碼共享外,其他都爲繼承父進程的資源,所以彼此也是分開的互不影響的兩個進程
在此獲取不同進程號代碼

    print('當前進程名',__name__)
    print("父進程號%s"%os.getppid())
    print("進程名",os.getpid())

在此處主要想讓自己注意的是進程的隊列,我們之前引導的隊列直接是
import queue
但是對於進程來說,資源互不分享,所以不回獲取到線程隊列,
所以我們需專門引入進程隊列
from multiprocessing import Queue
此處有個例子

# -*- coding: utf-8 -*-
#Author :The Y Devil
#在之前的線程當然,隊列queue可以互相訪問,但是在我們的進程中每個模塊都是獨立的,不能互相訪問
#所有要從進程模塊中導入Queue
from multiprocessing import Process,Queue
import queue
#q=queue.Queue()此方法會報錯,屬於線程的隊列
def n(q):
    q.put('123')


if __name__ == '__main__':
    q=Queue()#沒有共享一個q隊列,只是相當於克隆了一個q
    x=Process(target=n,args=(q,))
    x.start()
    print(q.get())


兩個進程管道通信:

# -*- coding: utf-8 -*-
#Author :The Y Devil


from  multiprocessing import Process,Pipe
#創建一個函數,兩個進程直接數據傳遞--管道
def talk(con):
    con.send(['1',2,'i'])#兩個管道互相通信,一個發送即另外個接收,相當於一次一次對接
    print(con.recv())
    con.close()
if __name__ == '__main__':
    parent_con,child_con=Pipe()
    parent_con.send('我在這')
    t=Process(target=talk,args=(child_con,))
    t.start()
    print(parent_con.recv())


只可以同時定義兩個管道,可以互相接收和發送消息,若接收時沒有消息則會一直等待

如何實現數據的共享呢?
我們在multiprocessing中有一個Manage()模塊,可以創建可共享的一些數據類型。
如:list, dict, Namespace, Lock, RLock, Semaphore, BoundedSemaphore, Condition, Event, Barrier, Queue, Value and Array
那我們來一起看看`

# -*- coding: utf-8 -*-
#Author :The Y Devil

from multiprocessing import  Process,Manager
import os
def sa(d,l):
    d[os.getpid()]=os.getpid()#把自己的pid號設置成字典
    l.append(os.getpid())
    #print(d)
    print(l)

if __name__ == '__main__':
    with Manager() as manage:#和打開文件方式有點相似   
        d=manage.dict( )
        #d={}
        l=manage.list(range(4))
        p_list=[]
        for i in range(10):
            m=Process(target=sa,args=(d,l))
            m.start()
            p_list.append(m)

        for res in p_list:
            res.join()

        print(d)
        print(l)


結果:
在這裏插入圖片描述
再此處,測試一下,把manage.dict()換成普通的dict來看看結果。並在父進程和子進程內都打印,在這裏屏蔽了列表的打印

在這裏插入圖片描述
每一個進程都字典都不一樣,說明數據未被共享,

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章