119 Python程序中的线程操作-线程同步

[TOC]

一、锁

线程中的锁机制和进程中一样。都是通过锁来控制资源访问虽然,线程中的资源是共享的,但也可以通过锁来进行控制。达到线程同步的目的。虽然牺牲了效率但是保证了安全。

x = 0
mutex = Lock()
def task():
    global x
    mutex.acquire() # 上锁
    for i in range(200000):
        x = x +1
    mutex.release() # 解锁

if __name__ == '__main__':
    th_list = []
    for i in range(10):
        t1 =  Thread(target=task())
        t1.start()
        th_list.append(t1)
    for i in th_list:
        i.join()
    print(x)

二、解决死锁问题---递归锁

**死锁问题:**死锁就是A等B,B等A,互相都在等锁的开启。因此会造成阻塞。

from threading import Thread,Lock,RLock
# 普通的锁,会出现死锁问题
mutex1 = Lock()
mutex2 = Lock()

import time
class MyThread(Thread):
    def run(self):
        self.task1()
        self.task2()
    def task1(self):
        mutex1.acquire()
        print(f'{self.name} 抢到了 锁1 ')
        mutex2.acquire()
        print(f'{self.name} 抢到了 锁2 ')
        mutex2.release()
        print(f'{self.name} 释放了 锁2 ')
        mutex1.release()
        print(f'{self.name} 释放了 锁1 ')

    def task2(self):
        mutex2.acquire()
        print(f'{self.name} 抢到了 锁2 ')
        time.sleep(1)       # 出现死锁问题。因为没有执行完,但是mutex1在别的线程中被上锁。mutex2在当前线程中被上锁。
        mutex1.acquire()
        print(f'{self.name} 抢到了 锁1 ')
        mutex1.release()
        print(f'{self.name} 释放了 锁1 ')
        mutex2.release()
        print(f'{self.name} 释放了 锁2 ')

for i in range(3):
    t = MyThread()
    t.start()

2.1 递归锁

递归锁 同一个线程内可以被多次acquire,但acquire了几次就要release几次内部相当于维护了一个计数器

# 递归锁,可以多次,多次解锁
mutex1 = RLock()
mutex2 = mutex1

import time
class MyThread(Thread):
    def run(self):
        self.task1()
        self.task2()
    def task1(self):
        mutex1.acquire()
        print(f'{self.name} 抢到了 锁1 ')
        mutex2.acquire()
        print(f'{self.name} 抢到了 锁2 ')
        mutex2.release()
        print(f'{self.name} 释放了 锁2 ')
        mutex1.release()
        print(f'{self.name} 释放了 锁1 ')

    def task2(self):
        mutex2.acquire()
        print(f'{self.name} 抢到了 锁2 ')
        time.sleep(1)       # 出现死锁问题。因为没有执行完,但是mutex1在别的线程中被上锁。mutex2在当前线程中被上锁。
        mutex1.acquire()
        print(f'{self.name} 抢到了 锁1 ')
        mutex1.release()
        print(f'{self.name} 释放了 锁1 ')
        mutex2.release()
        print(f'{self.name} 释放了 锁2 ')

for i in range(3):
    t = MyThread()
    t.start()

三、信号量

信号量就是加了计数器的锁

代表了同时可以有 多少人 在使用锁

from threading import Thread,currentThread, Semaphore
import time
def task():
    sem.acquire()
    print(f'{currentThread().name} 在执行')
    time.sleep(3)
    sem.release()

sem =  Semaphore(5)
for i in range(15):
    t = Thread(target=task)
    t.start()

你可能感兴趣的:(119 Python程序中的线程操作-线程同步)