06 并发编程-线程和锁

什么是线程

进程:资源分配单位

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

线程的两种创建方式:

from multiprocessing import Process
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锁

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

 

posted @ 2019-01-14 19:18  small_caier  阅读(228)  评论(0编辑  收藏  举报