Concurrent programming---daemon thread---mutex lock

Daemon thread

       The daemon process (daemon thread) will wait for the main process (main thread) to finish running and be destroyed

        Completion of the run does not terminate the run:

               1. For the main process: the completion of the operation refers to the completion of the main process code running

               2. For the main thread: the completion of the operation refers to the completion of all non-daemon threads in the process where the main thread is located, and the main thread is considered to have finished running.

       explain in detail:

              1. The main process has finished running after its code ends (the daemon process is recycled at this time), and then the main process will wait for the non-daemon sub-processes to run and recycle the resources of the sub-process (otherwise, it will generate zombie process), will end.

              2. The main thread does not finish running until other non-daemon threads finish running (the daemon thread is recycled at this time). Because the end of the main thread means the end of the process, the overall resources of the process will be reclaimed, and the process must ensure that all non-daemon threads are running before it can end.

from threading import Thread
import time

def sayhi(name):
    time.sleep(2)
    print('%s say hello' %name)

if __name__ == '__main__':
    t =Thread(target=sayhi,args=( ' egon ' ,))
     # t.setDaemon(True) #must set 
    t.daemon= True before t.start()
    t.start()

    print ( ' main thread ' )
     print (t.is_alive())
 '''
print result
main thread
True
''' 
#Think about what might be the result of the execution of the following code? Why? 
from threading import Thread
 import time

def foo():
    print(123)
    time.sleep(1)
    print("end123")

def bar():
    print(456)
    time.sleep(3)
    print("end456")

if __name__ == '__main__':
    t1=Thread(target=foo)
    t2=Thread(target=bar)

    t1.daemon=True
    t1.start()
    t2.start()
    print ( " main------- " ) # must wait until the non-daemon thread finishes executing before ending 
'''
print result:
123
456
main-------
end123
end456
'''
Daemon thread

Mutex

        In the Cpython interpreter, multi-threading under the same process can only be executed by one thread at the same time, which cannot take advantage of multi-core.

               The GIL is not a feature of Python, and Python can be completely independent of the GIL. Like JPython, there is no GIL. 

        Mutex: 

               Principle: Turn parallel into serial 

               Essence: Partial serialization, only for shared data modification. To protect different data, different locks should be used. 

'''
Mutex locks can improve program security, but reduce efficiency
'''
from  threading import Thread,Lock
import time
n = 100

def task():
    global n
    mutex.acquire() # 99 threads are stopped here waiting to grab the lock 
    temp = n
    time.sleep( 0.1) #Sleep for 0.1 seconds before locking, 100 threads have stopped here 
    n=temp-1
    mutex.release()

if __name__ == '__main__':
    mutex=Lock()
    t_l=[]
    for i in range(100):
        t = Thread(target=task)
        t_l.append(t)
        t.start()

    for t in t_l:
        t.join()

    print ( ' main thread ' ,n)
 '''
print result:
main thread 0
'''
Mutex

GIL(global interpreter lock)

      The GIL itself is a mutex

        In a python process, there are not only the main thread of test.py or other threads started by the main thread, but also interpreter-level threads such as garbage collection started by the interpreter. In short, all threads run in this process inside, without a doubt

   1.所有数据都是共享的,这其中,代码作为一种数据也是被所有线程共享的(test.py的所有代码以及Cpython解释器的所有代码)                                                                  例如:test.py定义一个函数work(代码内容如下图),在进程内所有线程都能访问到work的代码,于是我们可以开启三个线程然后target都指向该代码,能访问 到意味着就是可以执行。

      2.所有线程的任务,都需要将任务的代码当做参数传给解释器的代码去执行,即所有的线程要想运行自己的任务,首先需要解决的是能够访问到解释器的代码。

   执行流程:target=work
多个线程先访问到解释器的代码,即拿到执行权限,然后将target的代码交给解释器的代码去执行

      The code of the interpreter is shared by all threads, so the garbage collection thread may also access the code of the interpreter to execute, which leads to a problem: for the same data 100, thread 1 may execute x=100 at the same time, while Garbage collection performs the operation of recycling 100. There is no clever way to solve this problem, that is, locking processing, as shown in the GIL below, to ensure that the python interpreter can only execute the code of one task at a time

 GIL与Lock

GIL: is an interpreter-level lock used to protect interpreter-related data, such as garbage collection

Lock: is an application lock to protect application-related data

分析  :
1、100个线程去抢GIL锁,即抢执行权限
2、肯定有一个线程先抢到GIL(暂且称为线程1),然后开始执行,一旦执行就会拿到lock.acquire()
3、极有可能线程1还未运行完毕,就有另外一个线程2抢到GIL,然后开始运行,但线程2发现互斥锁lock还未被线程1释放,于是阻塞,被迫交出执行权限,即释放GIL
4、直到线程1重新抢到GIL,开始从上次暂停的位置继续执行,直到正常释放互斥锁lock,然后其他的线程再重复2 3 4的过程


 

 

      

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326276382&siteId=291194637