相关文档
线程与进程
线程是进程内一个执行单元,也是进程内的可调度实体。
线程与进程的区别:
- 地址空间,进程独立空间,线程共享进程内的地址空间
- 资源分配,进程是系统资源调度及分派的基本单位
- 线程是处理器调度的基本单位
- 二者均可实现并发
多线程:
线程的划分小,并行的效率高;
多线程共享内存单元,极大地提高了程序运行效率
Python线程模块
Python3支持线程的模块主要有thread和threading两个模块,thread是比较底层的模块,threading是对thread的一个封装的模块,threading比较方便以及好用。
Python3.x通过Threading模块创建新的线程有两种方法:
- 通过threading.Thread(target=executable Method),即通过传递给Thread对象一个可执行方法或对象;
- 继承threading.Thread定义子类并重写run()方法。
第2种方法中,唯一必须重写的方法是run()
(1) 通过threading.Thread() 进行创建多线程,即通过传递给thread对象一个可执行的方法(或对象)
import threading
import time
def target():
print(threading.current_thread().name, "1")
time.sleep(2)
print(threading.current_thread().name, "2")
# 当前主线程在运行
print(threading.current_thread().name, "3")
# 开启线程t, 一般按顺序赋予:Thread-1
t = threading.Thread(target=target)
t.start()
# join()是阻塞当前线程,此处的当前线程是主线程,
# 主线程直到Thread-1结束之后才结束, 所以最后结束的是主线程
t.join()
print(threading.current_thread().name, "4")
运行结果:
MainThread 3
Thread-1 1
Thread-1 2
MainThread 4
(2) 通过继承 threading.Thread 定义子类创建多线程
使用 threading 模块创建多线程,直接从 threading.Thread 继承,然后重写__init__() 方法和 run() 方法
import threading
import time
class MyThread(threading.Thread): #继承父类threading.Thread
def __init__(self, threadID, name, counter):
threading.Thread.__init__(self)
self.threadID = threadID
self.name = name
self.counter = counter
def run(self): #把要执行的代码写到run函数里面,线程在创建后会直接运行run
print("开始运行:" + self.name)
print(self.name, self.counter, 5)
print("结束运行:" + self.name)
def print_time(threadName, delay, counter):
while counter:
time.sleep(delay)
print("%s 进程 在:" % (threadName, time.ctime(time.time())))
counter -= 1
#创建新线程
thread_1 = MyThread(1, "Thread-1", 1)
thread_2 = MyThread(2, "Thread-2", 2)
#开启线程
thread_1.start()
thread_2.start()
#等待线程结束
thread_1.join()
thread_2.join()
运行结果:
开始运行:Thread-1
开始运行:Thread-2
Thread-1 1 5
Thread-2 2 5
结束运行:Thread-1
结束运行:Thread-2
这个结果有一定的变化。可以使用线程同步进行控制。
线程同步
如果多个线程共同对某个数据修改,则可能出现不可预料的结果,为了保证数据的正确性,需要对多个线程进行同步。
使用Thread对象的Lock和Rlock可以实现简单的线程同步,这两个对象都有acquire方法和release方法,对于那些需要每次只允许一个线程操作的数据,可以将其操作放到acquire和release方法之间。
需要注意的是,Python有一个GIL(Global Interpreter Lock)机制,任何线程在运行之前必须获取这个全局锁才能执行,每当执行完100条字节码,全局锁才会释放,切换到其他线程执行。
多线程实现同步有四种方法:
1、锁机制
2、信号量
3、条件判断
4、同步队列
1、锁机制实现示例
threading的Lock类,用该类的 acquire 函数进行加锁,用 realease 函数进行解锁
未完待续…