day39学习整理-并发编程

2019/09/18 学习整理

并发编程

线程锁

多个线程抢占资源的情况

from threading import Thread
import os, time


def work():
    global n
    temp = n
    time.sleep(0.1)
    n = temp - 1


if __name__ == '__main__':
    n = 100
    l = []
    for i in range(100):
        p = Thread(target=work)
        l.append(p)
        p.start()
    for p in l:
        p.join()

    print(n)  # 结果可能为99

使用线程锁解决线程修改数据混乱问题。

加锁后

from threading import Thread,Lock
import os,time
def work():
    global n
    lock.acquire()
    temp=n
    time.sleep(0.1)
    n=temp-1
    lock.release()
if __name__ == '__main__':
    lock=Lock()
    n=100
    l=[]
    for i in range(100):
        p=Thread(target=work)
        l.append(p)
        p.start()
    for p in l:
        p.join()

    print(n) #结果肯定为0,由原来的并发执行变成串行,牺牲了执行效率保证了数据安全

死锁问题

死锁:是指两个或两个以上的进程或线程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程

from threading import Lock as Lock
import time
mutexA=Lock()
mutexA.acquire()
mutexA.acquire()
print(123)
mutexA.release()
mutexA.release()

解决办法就是用递归锁

递归锁(RLock)

在Python中为了支持在同一线程中多次请求同一资源,python提供了可重入锁RLock

这个RLock内部维护着一个Lock和一个counter变量,counter记录了acquire的次数,从而使得资源可以被多次require。直到一个线程所有的acquire都被release,其他的线程才能获得资源。上面的例子如果使用RLock代替Lock,则不会发生死锁

from threading import RLock as Lock
import time
mutexA=Lock()
mutexA.acquire()
mutexA.acquire()
print(123)
mutexA.release()
mutexA.release()

信号量Semaphore

Semaphore管理一个内置的计数器,
每当调用acquire()时内置计数器-1;
调用release() 时内置计数器+1;
计数器不能小于0;当计数器为0时,acquire()将阻塞线程直到其他线程调用release()。

实例:(同时只有5个线程可以获得semaphore,即可以限制最大连接数为5):

from threading import Thread,Semaphore
import threading
import time


def task():
    sm.acquire()
    print(f"{threading.current_thread().name} get sm")
    time.sleep(3)
    sm.release()

if __name__ == '__main__':
    sm = Semaphore(5) # 同一时间只有5个进程可以执行。
    for i in range(20):
        t = Thread(target=task)
        t.start()

与进程池是完全不同的概念,进程池Pool(4),最大只能产生4个进程,而且从头到尾都只是这四个进程,不会产生新的,而信号量是产生一堆线程/进程

GIL

https://www.cnblogs.com/Wunsch/p/11542258.html

多线程与多进程

from threading import Thread
from multiprocessing import Process
import time

# 计算密集型
# def work1():
#     res=0
#     for i in range(100000000): #1+8个0
#         res*=i
#
# if __name__ == '__main__':
#     t_list = []
#     start = time.time()
#     for i in range(4):
#         # t = Thread(target=work1)
#         t = Process(target=work1)
#         t_list.append(t)
#         t.start()
#     for t in t_list:
#         t.join()
#     end = time.time()
#     # print('多线程',end-start) # 多线程 15.413789510726929
#     print('多进程',end-start) # 多进程 4.711405515670776


# # io密集型
# def work1():
#     x = 1+1
#     time.sleep(5)
#
#
# if __name__ == '__main__':
#     t_list = []
#     start = time.time()
#     for i in range(4):
#         t = Thread(target=work1)
#         # t = Process(target=work1)
#         t_list.append(t)
#         t.start()
#     for t in t_list:
#         t.join()
#     end = time.time()
#     print('多线程',end-start) #  多线程 5.002625942230225
#     # print('多进程',end-start) # 多进程 5.660863399505615

转载于:https://www.cnblogs.com/Wunsch/p/11542289.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值