1. 程式人生 > >守護進執行緒,互斥鎖,訊號量,佇列,死鎖遞迴鎖等

守護進執行緒,互斥鎖,訊號量,佇列,死鎖遞迴鎖等

守護程序:

from multiprocessing import Process
import os,time,random

def task():
    print('%s is running' %os.getpid())
    time.sleep(2)
    print('%s is done' %os.getpid())
    # p = Process(target=time.sleep, args=(3,))
    # p.start()

if __name__ == '__main__':
    p=Process(target=task)
    p.daemon = True #1、必須在p.start()之前 2:守護程序不能開啟子程序
    p.start()
    # p.join()
    print('主')
    '''
    舉例說明守護程序的應用場景:
        假設有兩個任務要幹,要玩出併發的效果,使用程序的話可以讓主程序
        執行一個任務,然後開啟一個子程序執行一個任務。

        如果這兩個任務毫無關係,那麼就像上面這麼做就可以
        如果主程序的任務在執行完畢後,子程序的任務沒有存在的意義了
        那麼該子程序應該在開啟之前就被設定成守護程序
    '''
迷惑人的例子 主程序程式碼執行完畢,守護程序就會結束
from multiprocessing import Process
from threading import Thread
import time
def foo():
    print(123)
    time.sleep(1)
    print("end123")

def bar():
    print(456)
    time.sleep(3)
    print("end456")

if __name__ == '__main__':
    p1=Process(target=foo)
    p2 = Process(target=bar)

    p1.daemon=True
    p1.start()
    p2.start()
    print("main-------") #列印該行則主程序程式碼結束,則守護程序p1應該被終止,可能會有p1任務執行的列印資訊123,
因為主程序列印main----時,p1也執行了,但是隨即被終止
互斥鎖三個例子:
from multiprocessing import Process,Lock
import os,time,random   # 
互斥鎖就是給整序列,比join好點,可以控制鎖的時間。
def task(mutex):
    mutex.acquire()
    print('%s print 1'%os.getpid())
    time.sleep(random.randint(1,2))
    print('%s print 2' % os.getpid())
    time.sleep(random.randint(1, 2))
    print('%s print 3' % os.getpid())
    time.sleep(random.randint(1, 2))
    mutex.release()
if __name__ == '__main__':
    mutex = Lock()
    p1 = Process(target=task,args=(mutex,))
    p2 = Process(target=task,args=(mutex,))
    p3 = Process(target=task,args=(mutex,))
    p1.start()
    p2.start()
    p3.start()
##########################################################
from multiprocessing import Process,Lock
import os,time,random,json
def search():
    with open('db.txt',encoding='utf-8') as f:
        dic=json.load(f)
        print('%s 剩餘票數 %s'%(os.getpid(),dic['count']))
def get():
    with open('db.txt',encoding='utf-8') as read_f:
        dic = json.load(read_f)
    if dic['count'] > 0:
        dic['count'] -= 1
        time.sleep(random.randint(1,3))
        with open('db.txt','w',encoding='utf-8')as write_f:
            json.dump(dic,write_f)
            print('%s 搶票成功'%os.getpid())
def task(mutex):
    search()
    mutex.acquire()
    get()
    mutex.release()

if __name__ == '__main__':
    mutex = Lock()
    for i in range(20):
        p = Process(target=task,args=(mutex,))
        p.start()
########################################################
from threading import Thread,Lock
import time
n = 100
def task(mutex):
    global n
    with mutex:    ### 相當於 那 兩行程式碼
        temp = n
        time.sleep(0.01)
        n = temp-1
if __name__ == '__main__':
    mutex = Lock()
    t_l = []
    for i in range(100):
        t = Thread(target=task,args=(mutex,))
### t = Thread(target=task)   # 因為是執行緒資源共享,所以不用傳參args=(mutex,)
        t_l.append(t)
        t.start()
    for i in t_l:
        i.join()
    print(n)    ############ 0

訊號量:

from multiprocessing import Process,Semaphore
# from threading import Thread,Semaphore
import time,random,os

def task(sm):
    with sm:
        print('%s 上廁所' %os.getpid())
        time.sleep(random.randint(1,3))

if __name__ == '__main__':
    sm=Semaphore(3)
    for i in range(10):
        p=Process(target=task,args=(sm,))
        p.start()
==============================================================================================================================
ipc機制 : 程序之間通訊,指的是用記憶體空間共享,來實現程序之間通訊: ①管道 ②佇列 frommultiprocessingimportQueue#程序佇列
q=Queue(3)    
若 定義為3,則放3個拿3個,超出則程序結束不了,一直等著。
q.put({'a':1})
q.put('xxxxx')
q.put(3)
q.put(4)

print(q.get())
print(q.get())
print(q.get())
print(q.get())
importqueue#執行緒佇列 佇列:先進先出
q=queue.Queue(3)
q.put({'a':1})
q.put('xxxxx')
q.put(3)
q.put(4)

print(q.get())
print(q.get())
print(q.get())
print(q.get())
優先順序佇列:數字越小優先順序越高
q=queue.PriorityQueue(3)
q.put((10,{'a':1}))
q.put((-1,'xxxxx'))
q.put((0,3))
# q.put(4)

print(q.get())
print(q.get())
print(q.get())
print(q.get())
堆疊:先進後出
q=queue.LifoQueue(3)
q.put({'a':1})
q.put('xxxxx')
q.put(3)
# q.put(4)

print(q.get())
print(q.get())
print(q.get())
print(q.get())

死鎖/遞迴鎖

from threading import Thread,Lock,RLock   # RLock 就是說可以多次拿鎖。
import time
# mutexA=mutexB=Lock()
mutexA=mutexB=RLock()   
###兩個鎖的時候會出現死鎖,一個拿到鎖卻沒釋放
class MyThread(Thread):
    def run(self):
        self.f1()
        self.f2()

    def f1(self):
        mutexA.acquire()
        print('%s 拿到A鎖' %self.name)

        mutexB.acquire()
        print('%s 拿到B鎖' %self.name)
        mutexB.release()

        mutexA.release()

    def f2(self):
        mutexB.acquire()
        print('%s 拿到B鎖' % self.name)
        time.sleep(0.1)
        mutexA.acquire()
        print('%s 拿到A鎖' % self.name)
        mutexA.release()

        mutexB.release()

if __name__ == '__main__':
    for i in range(10):
        t=MyThread()
        t.start()

終身美麗 --- 鄭秀文