python from entry to abandon the process lock lock

# ### lock (mutex)
"" "
# multi-process applications in which
# mutex lock: mutex is get_ticket between processes mutually exclusive
between processes, the first to seize the resource, who first locked until after unlocking the next process to continue to use

"""

 

lock.acquire () # locked
lock.release () # to unlock

# The same time allow Lock is a lock on a process
when locking ensures that multiple processes modifying the same piece of data, at the same time only one task can be modified, that is, serial (synchronous) changes, yes, speed is slow, but speed is sacrificed to ensure data security.
# Same time allows multiple processes on multiple lock is [semaphores Semaphore]
semaphore is a modification of the lock: locks actual implementation + is a counter, a plurality of processes while allowing the locking

# Mutex Lock: mutex is mutually exclusive processes, the first to grab resources, change will come to a locked resource content, in order to ensure the synchronization of data
# Note: multiple locks on together, do not lock, will cause death lock. lock and unlock a pair.

code show as below

= Lock Lock ()
 # locked 
lock.acquire ()
 Print (1 )
 # lock and unlock a pair, one to one relationship, if not only to unlock the lock, a deadlock occurs 
lock.acquire ()
 Print ( 2 ) 
lock.release () 

# to unlock 
lock.release ()

 

import json
# 读取票数,更新票数
def wr_info(sign,dic=None):
    if sign == "r":
        with open("ticket",mode="r",encoding="utf-8") as fp:
            dic = json.load(fp)
        return dic
    
    elif sign == "w":
        with open("ticket",mode="w",encoding="utf-8") as fp:
            json.dump(dic,fp)

This code function is performed according to my incoming state and return the appropriate conditions, if I was passed is a "r" Then I read in the current mode of the file which will read out the number of votes, and returns to call the office, if I pass a "w" mode so I'm currently writing mode to write my current state of the ticket folder

 

In the creation process is asynchronous created, carried out simultaneously in a locked time

 

Here are the abbreviations under Lock

A first lock object is instantiated

l=Lock()

with l:

  code...

Here equivalent to the traditional wording

l.acquire()
code...
l.release()

 Semaphore Semaphore

  At the same time can be a multi-lock that is first instantiate a semaphore object, and then specify the number you want to call from the locked process

 

 

1  # ### semaphores locks Semaphore is essentially the same time can multiple lock 
2  "" " 
3  # Syntax:
 . 4      SEM = Semaphore (3)
 . 5      sem.acquire ()
 . 6      sem.release ()
 . 7  " " " 
. 8  
. 9  Import Time
 10  Import Random
 . 11  from multiprocessing Import Process, Semaphore
 12 is  DEF KTV (Person, SEM):
 13 is      sem.acquire ()
 14      Print ( " % S into ktv, is singing " % (Person))
 15     time.sleep(random.randrange(3,6))
16     print("%s唱完了,离开了ktv" % (person))
17     sem.release()
18     
19 if __name__ == "__main__":
20     sem = Semaphore(3)
21     for i in range(10):
22         p = Process(target=ktv,args=("person%s" % (i), sem))    
23         p.start()
24         
25         
26 """
27 lock between multiple processes, can only be on a lock
 28  between Semaphore multiple processes, you can customize the number of locked, limited to a
 29  "" "

 

 

Usage above .....

 

 

# ### event (Event)

# Congestion events:
E = the Event () generated event object E
e.wait () procedure to add dynamic obstruction, obstructive program which depends entirely on whether the applied object is_set () [default return value is False]
# If True without blocking
# If False plus blocked

This value of the control attribute #
# SET () method to change the value of this attribute is True
# Clear () method to change the value of this attribute False
# is_set () method of determining whether the current attribute is True (the default is up False)

Event Event only for multi-process, in general synchronization process is Event event does not occur, then when I use event requires a minimum of a process to keep a child process to modify the state is True another process to acquire state in the state of modification False, the program will become a cause of sync, while maintaining close links between the two processes

Process to achieve the following events event by way of the code

 1 def traffic_light(e):
 2     # 默认红灯亮
 3     print("红灯亮")
 4     while True:
 5         if e.is_set():
 6             # 让绿灯亮1秒钟
 7             time.sleep(1)
 8             # 切换成红灯
 9             print("红灯亮")
10             # 把True 改成False
11             e.clear()
12         else:
13             # 让红灯亮1秒钟
14             time.sleep(1)
15             # 切换成绿灯
16             print("绿灯亮")
17             # 把默认值从False 改成True
18             e.set()
19             
20 # e = Event()
21 # traffic_light(e)
22 
23 def car(e,i):
24     # 判断如果是红灯亮,就执行下面代码
25     if not e.is_set():
26         print("car%s 在等待" % (i))
27         e.wait()
28     print("car%s 通行了" % (i))
29 
30 """
31 # 方法一
32 if __name__ == "__main__":
33     e = Event()
34     # 创建交通灯对象
35     p1 = Process(target=traffic_light,args=(e,))
36     p1.start()
37     
38     # 创建小车
39     for i in range(20):
40         time.sleep(random.randrange(0,2))
41         p2 = Process(target=car,args=(e,i))
42         p2.start()
43 """
44 
45 # 方法二:优化红绿灯代码[当小车执行结束的时候,把红绿灯终止]
46 if __name__ == "__main__":
47     lst = []
48     e = Event()
49     # 创建交通灯对象
50     p1 = Process(target=traffic_light,args=(e,))
51     p1.daemon=True
52     p1.start()
53     
54     # 创建小车
55     for i in range(20):
56         time.sleep(random.randrange(0,2))
57         p2 = Process(target=car,args=(e,i))
58         p2.start()
59         lst.append(p2)
60 
61     # 等所有小车都同行之后,在关闭守护进程
62     for i in lst:
63         i.join()
64 
65     print("主程序执行结束... ")

通过程序我们可以看出我们得通过事件的is_set方法来判定当前事件的状态是为False还是为True,为False执行car函数为True执行traffic_light函数

 

进程之队列

 

# ### 进程队列 [让进程之间共享资源]
from multiprocessing import Process,Queue
# 线程队列
import queue
"""先进先出"""

 

(1) 基本语法
q = Queue()
1.用put方法往队列中存值
q.put(111)
2.用get方法从队列中取值
res = q.get()
print(res)
3.当队列中没有值了,在调用get就会发生阻塞
res = q.get()
print(res)
4.get_nowait 在没值的时候,直接报错;存在兼容性问题(不推荐使用,报错报的是线程队列中的空,在取值时存在bug)
res = q.get_nowait()
print(res)

 

# (了解)
try:
res = q.get_nowait()
print(res)
except queue.Empty:
pass

 

# (2) 可以适用queue 指定队列长度
q1 = Queue(3)
q1.put(11)
q1.put(22)
q1.put(33)
注意:如果超出了队列的长度,直接阻塞
# q1.put(44)
注意:如果超出了队列的长度,直接报错(不推荐)
# q1.put_nowait(44)

# (3) 多进程之间共享数据
def func(q):
    # 2.在子进程中获取数据
    res = q.get()
    print(res)
    # 3.子进程添加数据
    q.put("bbb")
    
if __name__ == "__main__":
    q2 = Queue()
    p1 = Process(target=func,args=(q2,))
    p1.start()
    
    # 1.在主进程中,添加数据
    q2.put("aaa")
    
    # 为了能够拿到子进程中添加的队列元素,需要等待子进程执行结束后在获取
    p1.join()
    
    # 4.主进程获取子进程添加的数据
    res = q2.get()
    print("主进程执行结束: 值%s" % (res))

生产者与消费者模型

 1 # (1) 基本语法
 2 from multiprocessing import Process,Queue
 3 import time,random
 4 # (1) 优化生产者和消费者模型 [生产者生产多少,对应的就消费多少]
 5 # 消费者模型
 6 def consumer(q,name):
 7     while True:
 8         food = q.get()
 9         if food is None:
10             break
11         time.sleep(random.uniform(0.1,1))
12         print("%s 吃了一个%s" % (name,food))
13     
14 # 生产者模型
15 def producer(q,name,food):
16     for i in range(5):
17         time.sleep(random.uniform(0.1,1))
18         print("%s 生产了 %s%s" % (name,food,i))
19         q.put(food+str(i))
20 
21 if __name__ == "__main__":
22     q = Queue()
23     # 创建生产者
24     p1 = Process(target=producer,args=(q,"周永玲","便便"))
25     p1.start()
26     
27     # 创建生产者2号
28     p2 = Process(target=producer,args=(q,"常远","茶叶"))
29     p2.start()
30     
31     # 创建消费者
32     c1 = Process(target=consumer,args=(q,"张龙"))
33     c1.start()
34     
35     # 创建消费者2号
36     c2 = Process(target=consumer,args=(q,"林银展"))
37     c2.start()
38     
39     p1.join()
40     p2.join()
41     
42     # 在生产完所有数据之后,在队列的最后塞进去一个None,用来表达已经生产完所有数据;
43     q.put(None) #  便便0 便便1 便便2 便便3 便便4 None
44     q.put(None) #  便便0 便便1 便便2 便便3 便便4 茶叶1 茶叶2 茶叶3 茶叶4 None None
45 
46     print("主程序执行结束 ... ")

 

JoinableQueue 阻塞事件

put 存放
get 获取
task_done 队列数据减一
join 阻塞

task_done 与 join 通过一个中间变量统计队列中元素个数
每放入一个值 , 成员中的中间变量值加1
没执行一次task_done,成员中的中间变量值减1
join 会根据中间变量值来确定是阻塞还是放行
如果中间变量是0 意味着放行
如果中间变量不是0 意味着阻塞

1 # (1) 基本语法

2 """
3 jq = JoinableQueue()
4 jq.put("aabbcc")
5 print(jq.get())
6 jq.task_done()
7 jq.join()
8 print("finish")
9 """

 

生产者与消费者模型改造

# 消费者模型
def consumer(q,name):
    while True:
        food = q.get()
        time.sleep(random.uniform(0.1,1))
        print("%s 吃了一个%s" % (name,food))
        q.task_done()
# 生产者模型
def producer(q,name,food):
    for i in range(5):
        time.sleep(random.uniform(0.1,1))
        print("%s 生产了 %s%s" % (name,food,i))
        q.put(food+str(i))

if __name__ == "__main__":
    # 创建队列
    jq = JoinableQueue()
    # 消费者进程
    c1 = Process(target=consumer,args=(jq,"张晓东"))
    c1.daemon = True
    c1.start()
    
    # 生产者进程
    p1 = Process(target=producer,args=(jq,"黄乐锡","大茄子"))
    p1.start()
    
    # 等待生产者把所有数据放到队列中;
    p1.join()
    # 直到所有数据被消费完毕之后,放行;
    jq.join()
    
    print("主进程执行结束 ... ")

  # ### Manager  list dict 能够实现进程之间的数据共享

 

如果多个进程同时修改同一份共享数据,这个时候需要加锁,保证数据的准确性

 

(1) dict list 可以实现进程之间的数据共享
(2) 为了保证数据的准确性,需要加锁

 

manager实现的原理跟队列的实现原理是一样的,但又有所区别,队列时直接对元素进行操作的,而manager是直接对字典或list进行操作的,本质是一样的,但内容不同

 1 from multiprocessing import Process,Manager,Lock
 2 def work(dic,lock):
 3     # with 语法 可以自动的上锁和解锁
 4     with lock:
 5         dic["count"] -= 1
 6     """
 7     lock.acquire()
 8     dic["count"] -= 1
 9     lock.release()
10     """
11     
12 if __name__ == "__main__":
13     lst = []
14     # 创建一把锁
15     lock = Lock()
16     m = Manager()
17     dic = m.dict( {"count":10000} )
18     
19     for i in range(100):
20         p = Process(target=work,args=(dic,lock))
21         p.start()
22         lst.append(p)
23     
24     for i in lst:
25         i.join()
26     
27     print(dic,type(dic))
28     
29     
30     
31     

 

 

 

 

 

 

 

Guess you like

Origin www.cnblogs.com/zyling/p/11862652.html