码迷,mamicode.com
首页 > 编程语言 > 详细

python-进程与线程 三

时间:2020-03-27 21:28:00      阅读:56      评论:0      收藏:0      [点我收藏+]

标签:加锁   情况下   __name__   资源   target   elf   count   一个   共享   

一、锁的作用

  锁的作用是:使进程产生同步,确保数据的一致性。

二、线程安全和非线程安全

  a = 1 ,两个线程分别给a加一次1,理想结果是 a = 3(线程安全)

  如果两个线程同时拿到a=1的状态,分别加上1,那么a = 2(非线程安全)

  非线程安全转换为线程安全时,就需要在非线程安全上加上锁

三、代码

# 锁1 (Lock:给一个进程指定一把锁)
from multiprocessing import Process
import time


def l(num):

    time.sleep(0.2)
    print("Hello Num: %s" % (num))
    time.sleep(0.2)
    print("Hello Num: %s" % (num))
    time.sleep(0.2)
    print("Hello Num: %s" % (num))


if __name__ == __main__:
    for num in range(50):
        Process(target=l, args=(num,)).start()
结果:
Hello Num: 0
Hello Num: 1
Hello Num: 5
Hello Num: 43
Hello Num: 22
Hello Num: 6
。
。
。
Hello Num: 31
Hello Num: 28
Hello Num: 35
Hello Num: 48
Hello Num: 26
Hello Num: 27
# 结论:没有锁的情况下,子进程拿到数字就会去执行任务,导致打印的数字没有顺序

# 用函数的方式加锁
from multiprocessing import Process, Lock
import time


def l(lock, num):
    lock.acquire()  # 获得锁
    time.sleep(0.02)
    print("Hello Num: %s" % (num))
    time.sleep(0.02)
    print("Hello Num: %s" % (num))
    time.sleep(0.02)
    print("Hello Num: %s" % (num))
    lock.release()  # 释放锁


if __name__ == __main__:
    lock = Lock()  # 创建一个共享锁实例
    for num in range(50):
        Process(target=l, args=(lock, num)).start()
结果:
Hello Num: 15
Hello Num: 15
Hello Num: 15
Hello Num: 13
Hello Num: 13
Hello Num: 13
。
。
。
Hello Num: 37
Hello Num: 37
Hello Num: 37
Hello Num: 23
Hello Num: 23
Hello Num: 23

# 结论:上了锁之后,子进程拿到数字后要等前边的进程出来了,释放了锁它才能进去执行,所有执行结果3个打印是一样的。


# 通过类的方式进行加锁的操作

import time
from multiprocessing import Process, Value, Lock


class Counter(object):
    def __init__(self, initval=0):
        self.val = Value(i, initval)  # 全局共享变量,i 是指整型,d 是指双精度小鼠
        self.lock = Lock()  # 初始化了一个锁

    def increment(self):  # 在加锁的情况下,进行数字累加1
        with self.lock:  # 这个是加锁操作
            self.val.value += 1  # 共享变量自加1
            # print("increment one time!",self.value())
            # 加此句死锁

    def value(self):  # 读取的时候也是加锁的
        with self.lock:  # 这个是加锁操作,和上面那个的区别是:这个是加锁和释放锁都是自动完成的。
            return self.val.value


def func(counter):
    for i in range(50):
        time.sleep(0.01)
        counter.increment()


if __name__ == __main__:
    counter = Counter(0)
    procs = [Process(target=func, args=(counter,)) for i in range(10)]
    for p in procs: p.start()
    for p in procs: p.join()
    print(counter.value())

结果:
500

 

# 锁2:(Semaphore:给多个进程上多把锁,就是限制几个进程可以同时并发)
import multiprocessing
import time


def worker(s, i):
    s.acquire()  # 加锁
    print(multiprocessing.current_process().name + " acquire")
    time.sleep(i)
    print(multiprocessing.current_process().name + " release")
    s.release()  # 释放锁


if __name__ == "__main__":
    # 设置限制最多3个进程同时访问共享资源
    s = multiprocessing.Semaphore(3)
    for i in range(5):
        p = multiprocessing.Process(target=worker, args=(s, i * 2))
        p.start()
        
结果:
Process-1 acquire
Process-1 release
Process-3 acquire
Process-2 acquire
Process-2 release
Process-4 acquire
Process-3 release
Process-5 acquire
Process-4 release
Process-5 release

python-进程与线程 三

标签:加锁   情况下   __name__   资源   target   elf   count   一个   共享   

原文地址:https://www.cnblogs.com/su-sir/p/12584146.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!