python并发编程之线程(创建线程,锁(死锁现象,递归锁),GIL锁)

Posted 吾有一剑

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python并发编程之线程(创建线程,锁(死锁现象,递归锁),GIL锁)相关的知识,希望对你有一定的参考价值。

什么是线程

进程:资源分配单位

线程:cpu执行单位(实体),每一个py文件中就是一个进程,一个进程中至少有一个线程

线程的两种创建方式:

from threading import Thread
def f1(n):
    print(n,\'号线程\')

if __name__ == \'__main__\':
    t1 = Thread(target=f1,args=(1,))
    t1.start()
    print(\'主线程\'

from threading import Thread
class MyThread(Thread):
    def __init__(self,name):
        super().__init__()
        self.name = name

    def run(self):
        print(\'hello:\' + self.name)

if __name__ == \'__main__\':

    t = MyThread(\'haha\')
    t.start()
    print(\'主线程结束\')

 

线程的创建和销毁,相对于进程来说开销特别小

线程之间资源共享,共享的是同一个进程中的资源,  资源共享就涉及到数据安全问题,加锁来解决

 

线程锁

From threading import Thread,Lock

def f1: 

  Loc.acquire()

  代码

  Loc.release()

main

  Loc = Lock()

  T = thread(target=f1,args=(loc,)

from multiprocessing import Queue
import queue
import time
from threading import Lock,Thread

num = 100
def f1(loc):
    loc.acquire()
    global num
    tmp = num
    tmp -= 1
    time.sleep(0.001)
    num = tmp
    loc.release()

if __name__ == \'__main__\':

    t_loc = Lock()
    t_list = []
    for i in range(10):
        t = Thread(target=f1,args=(t_loc,))
        t.start()
        t_list.append(t)
    [tt.join() for tt in t_list]
    print(\'主线的num\',num)

锁:牺牲了效率,保证了数据安

死锁现象(天长地久,永不分离):

出现在锁嵌套的时候,双方互相抢对方已经拿到的锁,导致双方互相等待,这就是死锁现象

import time
from threading import Thread,Lock,RLock

def f1(locA,locB):
    locA.acquire()
    print(\'f1>>1号抢到了A锁\')
    time.sleep(1)
    locB.acquire()
    print(\'f1>>1号抢到了B锁\')
    locB.release()

    locA.release()
def f2(locA,locB):
    locB.acquire()

    print(\'f2>>2号抢到了B锁\')

    locA.acquire()
    time.sleep(1)
    print(\'f2>>2号抢到了A锁\')
    locA.release()

    locB.release()
if __name__ == \'__main__\':
    locA = Lock()
    locB = Lock()
    t1 = Thread(target=f1,args=(locA,locB))
    t2 = Thread(target=f2,args=(locA,locB))
    t1.start()
    t2.start()

递归锁:

解决死锁现象

Rlock  首先本身就是个互斥锁,维护了一个计数器,每次acquire就+1,release就-1,当计数器为0的时候,大家才能抢这个锁

 

import time
from threading import Thread, Lock, RLock

def f1(locA, locB):
    locA.acquire()
    print(\'f1>>1号抢到了A锁\')
    time.sleep(1)
    locB.acquire()
    print(\'f1>>1号抢到了B锁\')
    locB.release()
    locA.release()

def f2(locA, locB):
    locB.acquire()
    print(\'f2>>2号抢到了B锁\')
    locA.acquire()
    time.sleep(1)
    print(\'f2>>2号抢到了A锁\')
    locA.release()
    locB.release()

if __name__ == \'__main__\':

    locA = locB = RLock()  
    t1 = Thread(target=f1, args=(locA, locB))
    t2 = Thread(target=f2, args=(locA, locB))
    t1.start()
    t2.start()

 

守护线程:

守护线程:等待所有非守护线程的结束才结束

守护进程:主进程代码运行结束,守护进程就随之结束

 

import time
from threading import Thread
from multiprocessing import Process

def f1():
    time.sleep(2)
    print(\'1号线程\')
def f2():
    time.sleep(3)
    print(\'2号线程\')

if __name__ == \'__main__\':
    t1 = Thread(target=f1,)
    t2 = Thread(target=f2,)
    t2.daemon = True
    t1.start()
    t2.start()
    print(\'主线程结束\')

GIL锁 :

  cpython解释器上的一把互斥锁,当线程需要进入cpu做运算时必须一个一个经过GIL锁

 

线程的事件,信号量 与进程的事件,信号量 用法相同.

以上是关于python并发编程之线程(创建线程,锁(死锁现象,递归锁),GIL锁)的主要内容,如果未能解决你的问题,请参考以下文章

百万年薪python之路 -- 并发编程之 多线程 二

python 并发编程 多线程 死锁现象与递归锁

day10-python并发编程之多线程协程及MySQL

Python并发编程05/ 死锁/递归锁/信号量/GIL锁/进程池/线程池

Python——并发编程02

python-day36--并发编程之多线程