09-19-周五_14-48-32
This commit is contained in:
@@ -31,7 +31,7 @@
|
||||
|
||||
### 使用线程的实际场景
|
||||
|
||||
开启一个字处理软件进程,该进程肯定需要办不止一件事情,比如监听键盘输入,处理文字,定时自动将文字保存到硬盘,这三个任务操作的都是同一块数据,因而不能用多进程。只能在一个进程里并发地开启三个线程,如果是单线程,那就只能是,键盘输入时,不能处理文字和自动保存,自动保存时又不能输入和处理文字。
|
||||
开启一个软件进程,该进程肯定需要办不止一件事情,比如监听键盘输入,处理文字,定时自动将文字保存到硬盘,这三个任务操作的都是同一块数据,因而不能用多进程。只能在一个进程里并发地开启三个线程,如果是单线程,那就只能是,键盘输入时,不能处理文字和自动保存,自动保存时又不能输入和处理文字。
|
||||
|
||||
### 内存中的线程
|
||||
|
||||
@@ -50,9 +50,9 @@
|
||||
### 全局解释器锁GIL
|
||||
|
||||
Python代码的执行由Python虚拟机(也叫解释器主循环)来控制。Python在设计之初就考虑到要在主循环中,同时只有一个线程在执行。虽然 Python 解释器中可以“运行”多个线程,但在任意时刻只有一个线程在解释器中运行。
|
||||
对Python虚拟机的访问由全局解释器锁(GIL)来控制,正是这个锁能保证同一时刻只有一个线程在运行。
|
||||
对Python虚拟机的访问由全局解释器锁(GIL)来控制,正是这个锁能保证同一时刻只有一个线程在运行。
|
||||
|
||||
在多线程环境中,Python 虚拟机按以下方式执行:
|
||||
在多线程环境中,Python 虚拟机按以下方式执行:
|
||||
|
||||
1. 设置 GIL;
|
||||
|
||||
@@ -65,7 +65,8 @@ Python代码的执行由Python虚拟机(也叫解释器主循环)来控制。Pyt
|
||||
5. 解锁 GIL;
|
||||
|
||||
6. 再次重复以上所有步骤。
|
||||
在调用外部代码(如 C/C++扩展函数)的时候,GIL将会被锁定,直到这个函数结束为止(由于在这期间没有Python的字节码被运行,所以不会做线程切换)编写扩展的程序员可以主动解锁GIL。
|
||||
|
||||
在调用外部代码(如 C/C++扩展函数)的时候,GIL将会被锁定,直到这个函数结束为止(由于在这期间没有Python的字节码被运行,所以不会做线程切换)编写扩展的程序可以主动解锁GIL。
|
||||
|
||||
### python线程模块的选择
|
||||
|
||||
@@ -87,7 +88,7 @@ def sayhi(name):
|
||||
print('%s say hello' %name)
|
||||
|
||||
if __name__ == '__main__':
|
||||
t=Thread(target=sayhi,args=('aaron',))
|
||||
t=Thread(target=sayhi,args=('张三',))
|
||||
t.start()
|
||||
print('主线程')
|
||||
```
|
||||
@@ -107,7 +108,7 @@ class Sayhi(Thread):
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
t = Sayhi('aaron')
|
||||
t = Sayhi('张三')
|
||||
t.start()
|
||||
print('主线程')
|
||||
```
|
||||
@@ -256,7 +257,7 @@ import os
|
||||
def work():
|
||||
import time
|
||||
time.sleep(3)
|
||||
print(threading.current_thread().getName())
|
||||
print(threading.current_thread().name)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
@@ -264,7 +265,7 @@ if __name__ == '__main__':
|
||||
t=Thread(target=work)
|
||||
t.start()
|
||||
|
||||
print(threading.current_thread().getName())
|
||||
print(threading.current_thread().name)
|
||||
print(threading.current_thread()) #主线程
|
||||
print(threading.enumerate()) #连同主线程在内有两个运行的线程
|
||||
print(threading.active_count())
|
||||
@@ -281,7 +282,7 @@ def sayhi(name):
|
||||
print('%s say hello' %name)
|
||||
|
||||
if __name__ == '__main__':
|
||||
t=Thread(target=sayhi,args=('aaron',))
|
||||
t=Thread(target=sayhi,args=('张三',))
|
||||
t.start()
|
||||
t.join()
|
||||
print('主线程')
|
||||
@@ -305,8 +306,8 @@ def sayhi(name):
|
||||
print('%s say hello' %name)
|
||||
|
||||
if __name__ == '__main__':
|
||||
t=Thread(target=sayhi,args=('aaron',))
|
||||
t.setDaemon(True) #必须在t.start()之前设置
|
||||
t=Thread(target=sayhi,args=('张三',))
|
||||
t.daemon = True #必须在t.start()之前设置
|
||||
t.start()
|
||||
|
||||
print('主线程')
|
||||
@@ -433,8 +434,7 @@ from threading import current_thread,Thread,Lock
|
||||
import os,time
|
||||
def task():
|
||||
#未加锁的代码并发运行
|
||||
time.sleep(3)
|
||||
print('%s start to run' %current_thread().getName())
|
||||
print('%s start to run' %current_thread().name)
|
||||
global n
|
||||
#加锁的代码串行运行
|
||||
lock.acquire()
|
||||
@@ -459,34 +459,10 @@ if __name__ == '__main__':
|
||||
```
|
||||
|
||||
有的同学可能有疑问:既然加锁会让运行变成串行,那么我在start之后立即使用join,就不用加锁了啊,也是串行的效果啊
|
||||
没错:在start之后立刻使用jion,肯定会将100个任务的执行变成串行,毫无疑问,最终n的结果也肯定是0,是安全的,但问题是
|
||||
没错:在start之后立刻使用join,肯定会将100个任务的执行变成串行,毫无疑问,最终n的结果也肯定是0,是安全的,但问题是
|
||||
start后立即join:任务内的所有代码都是串行执行的,而加锁,只是加锁的部分即修改共享数据的部分是串行的
|
||||
单从保证数据安全方面,二者都可以实现,但很明显是加锁的效率更高.
|
||||
|
||||
```python
|
||||
from threading import current_thread,Thread,Lock
|
||||
import os,time
|
||||
def task():
|
||||
time.sleep(3)
|
||||
print('%s start to run' %current_thread().getName())
|
||||
global n
|
||||
temp=n
|
||||
time.sleep(0.5)
|
||||
n=temp-1
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
n=100
|
||||
lock=Lock()
|
||||
start_time=time.time()
|
||||
for i in range(100):
|
||||
t=Thread(target=task)
|
||||
t.start()
|
||||
t.join()
|
||||
stop_time=time.time()
|
||||
print('主:%s n:%s' %(stop_time-start_time,n))
|
||||
```
|
||||
|
||||
### 死锁与递归锁
|
||||
|
||||
两个或两个以上的进程或线程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为**死锁进程**
|
||||
|
Reference in New Issue
Block a user