python-进程与线程 三

JasonYeung 2020-03-27

一、锁的作用

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

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

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

相关推荐

zhuxianfeng / 0评论 2020-02-09