python3 GIL lock / Lock and recursive mutex lock Rlock

Lock GIL (Global Interpreter Lock) global interpreter lock 
multithreading Cpython interpreter, the same process has been started, the same time only one thread of execution, unable to take advantage of multi-core advantage.

So, we changed how to solve the problem then lock GIL ?

  1. Replace cpython is jpython (not recommended)

  2. Using multi-process multi-threaded task completion

  3. Use of multiple threads can use c language to realize

Question 1: When will release the GIL lock ?

1 encountered as I / O operations that will result in the case of cpu time Availability idle release GIL
2 there will be a specialized ticks are counted once the ticks value reaches 100 this time between the release of GIL GIL lock lock thread starts competition (Description : ticks this value can be set to extend or reduce the time to get Gil thread lock using the cpu)

2 issues: the relationship between GIL and mutex lock ?

GIL lock: to ensure that only one thread can use to cpu
mutex: multi-threaded, to ensure orderly when modifying shared data modification, data modification does not generate confusion


first assumed that only one process, this process two threads Thread1, Thread2, shared data to be modified date, and there mutex

the following steps

(1) multi-thread operation, it is assumed Thread1 GIL obtained may be used cpu, Thread1 obtained mutex lock case, date data can be changed Thread1 (but did not start modifying data)

(2) Thread1 thread occurs before modification date data of the I / O operation or ticks count over 100 (note that there is no operation to modify the data of data), this time Thread1 let out GIL, GIL lock can be competitive

(. 3) Thread1 and Thread2 start competition GIL (Note: If Thread1 because the I / O blocking to get out of GIL Thread2 must get GIL, if Thread1 because ticks count over 100 GIL let out this time Thread1 Thread2 and fair competition)

(4) just assume Thread2 won the GIL, run the code to modify the shared data date, due Thread1 have a mutex lock, so you can not change shared data Thread2 date, then let out Thread2 GIL lock, competition GIL lock recurrence


(5) assume Thread1 and grabbed GIL , because of its mutual exclusion lock so the data can continue to modify shared data, when you modify Thread1 releases the mutex lock data, data to be modified before Thread2 after obtaining the lock GIL

described above and mutex lock GIL of a relationship.

# -*- coding: utf-8 -*-
import time
from threading import Thread, Lock

n = 10
def func():
    with mutex:
        global n
        temp = n
        time.sleep(0.5)
        n = temp - 1


if __name__ == '__main__':
    '''线程之间数据是共享的,加锁来保护为了保护共享的数据,缺点线程变成了串行'''
    mutex = Lock()  # 线程不需要传递这把锁,子线程可以直接使用
    t_l = []
    for i in range(10):
        t = Thread(target=func)
        t_l.append(t)
        t.start()
    [tt.join() for tt in t_l]
    print(n)


# 0

 

# -*- coding: utf-8 -*-
import threading
from threading import Thread, Lock


def func():
    lockA.acquire()
    print("%s拿到A锁" % threading.current_thread().getName())
    lockB.acquire()
    print("%s拿到B锁" % threading.current_thread().getName())
    lockB.release()
    print("%s释放B锁" % threading.current_thread().getName())
    lockA.release()
    print("%s释放A锁" % threading.current_thread().getName())

    lockB.acquire()
    print("%s拿到B锁" % threading.current_thread().getName())
    lockA.acquire()
    print("%s拿到A锁" % threading.current_thread().getName())
    lockA.release()
    print("%s释放A锁" % threading.current_thread().getName())
    lockB.release()
    print("%s释放B锁" % threading.current_thread().getName())


if __name__ == '__main__':
    '''死锁现象,在同一进程的多个线程,一个线程所需要的锁,被另外一个线程抢到了'''
    lockA = Lock()
    lockB = Lock()
    for i in range(10):
        t = Thread(target=func)
        t.start()

# Thread-1拿到A锁
# Thread-1拿到B锁
# Thread-1释放B锁
# Thread-1释放A锁
# Thread-2拿到A锁
# Thread-1拿到B锁

 

# -*- coding: utf-8 -*-
import threading
from threading import Thread, RLock


def func():
    mutex.acquire()
    print("%s拿到锁" % threading.current_thread().getName())
    mutex.acquire()
    print("%s拿到锁" % threading.current_thread().getName())
    mutex.release()
    print("%s释放锁" % threading.current_thread().getName())
    mutex.release()
    print("%s释放锁" % threading.current_thread().getName())

    mutex.acquire()
    print("%s拿到锁" % threading.current_thread().getName())
    mutex.acquire()
    print("%s拿到锁" % threading.current_thread().getName())
    mutex.release()
    print("%s释放锁" % threading.current_thread().getName())
    mutex.release()
    print("%s释放锁" % threading.current_thread().getName())


if __name__ == '__main__':
    '''递归锁,是计数机制,acquire一次计数加一,release一次计数减一,只有计数为0的时候,线程间才是再次抢锁'''
    mutex = RLock()
    for i in range(10):
        t = Thread(target=func)
        t.start()

# Thread-1拿到锁
# Thread-1拿到锁
# Thread-1释放锁
# Thread-1释放锁
# Thread-2拿到锁
# Thread-2拿到锁
# Thread-2释放锁
# Thread-2释放锁
# Thread-1拿到锁
# Thread-1拿到锁
# Thread-1释放锁
# Thread-1释放锁
# Thread-2拿到锁
# Thread-2拿到锁
# Thread-2释放锁
# Thread-2释放锁
# Thread-3拿到锁
# Thread-3拿到锁
# Thread-3释放锁
# Thread-3释放锁
# Thread-4拿到锁
# Thread-4拿到锁
# Thread-4释放锁
# Thread-4释放锁
# Thread-5拿到锁
# Thread-5拿到锁
# Thread-5释放锁
# Thread-5释放锁
# Thread-3拿到锁
# Thread-3拿到锁
# Thread-3释放锁
# Thread-3释放锁
# Thread-6拿到锁
# Thread-6拿到锁
# Thread-6释放锁
# Thread-6释放锁
# Thread-4拿到锁
# Thread-4拿到锁
# Thread-4释放锁
# Thread-4释放锁
# Thread-7拿到锁
# Thread-7拿到锁
# Thread-7释放锁
# Thread-7释放锁
# Thread-5拿到锁
# Thread-5拿到锁
# Thread-5释放锁
# Thread-5释放锁
# Thread-8拿到锁
# Thread-8拿到锁
# Thread-8释放锁
# Thread-8释放锁
# Thread-9拿到锁
# Thread-9拿到锁
# Thread-9释放锁
# Thread-9释放锁
# Thread-6拿到锁
# Thread-6拿到锁
# Thread-6释放锁
# Thread-6释放锁
# Thread-10拿到锁
# Thread-10拿到锁
# Thread-10释放锁
# Thread-10释放锁
# Thread-7拿到锁
# Thread-7拿到锁
# Thread-7释放锁
# Thread-7释放锁
# Thread-8拿到锁
# Thread-8拿到锁
# Thread-8释放锁
# Thread-8释放锁
# Thread-9拿到锁
# Thread-9拿到锁
# Thread-9释放锁
# Thread-9释放锁
# Thread-10拿到锁
# Thread-10拿到锁
# Thread-10释放锁
# Thread-10释放锁

 

 

Guess you like

Origin www.cnblogs.com/lilyxiaoyy/p/11031986.html