python 多线程操作
一、概念
1.什么是线程?
线程也叫轻量级进程,是操作系统能够进行运算调度的最小单位,它被包涵在进程之中,是进程中的实际运作单位。
线程自己不拥有系统资源,只拥有一点儿在运行中必不可少的资源,但它可与同属一个进程的其他线程共享进程所拥有的全部资源。一个线程可以创建和撤销另一个线程,同一个进程中的多个线程之间可以并发执行
2.为什么使用多线程
线程在程序中是独立的、并发的执行流。与分隔的进程相比,进程中线程之间的隔离程度要小,它们共享内存、文件句柄
和其他进程应有的状态。因为线程的划分尺度小于进程,使得多线程程序的并发性高。进程在执行过程之中拥有独立的内存单元,而多个线程共享内存,从而极大的提升了程序的运行效率。
线程比进程具有更高的性能,这是由于同一个进程中的线程都有共性,多个线程共享一个进程的虚拟空间。线程的共享环境包括进程代码段、进程的共有数据等,利用这些共享的数据,线程之间很容易实现通信。
操作系统在创建进程时,必须为改进程分配独立的内存空间,并分配大量的相关资源,但创建线程则简单得多。因此,使用多线程来实现并发比使用多进程的性能高得要多。
3.线程的优点:
①进程之间不能共享内存,但线程之间共享内存非常容易。
② 操作系统在创建进程时,需要为该进程重新分配系统资源,但创建线程的代价则小得多。因此使用多线程来实现多任务并发执行比使用多进程的效率高
③python语言内置了多线程功能支持,而不是单纯地作为底层操作系统的调度方式,从而简化了python的多线程编程。
二、Python中使用线程有两种方式:函数或者用类来包装线程对象。
1.函数式:调用 _thread 模块中的start_new_thread()函数来产生新线程。语法如下:
_thread.start_new_thread ( function, args(, kwargs) )
参数说明:
function - 线程函数。
args - 传递给线程函数的参数,他必须是个tuple类型。
kwargs - 可选参数。
import _thread
import time
def thread_1():
while(1):
print("hello")
time.sleep(1)
return
def thread_2():
while(1):
print("world")
time.sleep(1)
return
def main():
try:
_thread.start_new_thread(thread_1,())
_thread.start_new_thread(thread_2,())
except Exception as e:
print("线程创建失败---异常---:", e)
while 1:
pass
main()
2.使用 threading 模块创建线程
Python3 通过两个标准库 _thread 和 threading 提供对线程的支持。
_thread 提供了低级别的、原始的线程以及一个简单的锁,它相比于 threading 模块的功能还是比较有限的。
threading 模块除了包含 _thread 模块中的所有方法外,还提供的其他方法:
threading.currentThread(): 返回当前的线程变量。
threading.enumerate(): 返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前,不包括启动前和终止后的线程。
threading.activeCount(): 返回正在运行的线程数量,与len(threading.enumerate())有相同的结果。
除了使用方法外,线程模块同样提供了Thread类来处理线程,Thread类提供了以下方法:
run(): 用以表示线程活动的方法。
start():启动线程活动。
join([time]): 等待至线程中止。这阻塞调用线程直至线程的join() 方法被调用中止-正常退出或者抛出未处理的异常-或者是可选的超时发生。
isAlive(): 返回线程是否活动的。
getName(): 返回线程名。
setName(): 设置线程名。
我们可以通过直接从 threading.Thread 继承创建一个新的子类,并实例化后调用 start() 方法启动新线程,即它调用了线程的 run() 方法:
class MyThread(threading.Thread):
def __init__(self,n):
super(MyThread,self).__init__() #重构run函数必须写
self.n = n
def run(self):
print('task',self.n)
time.sleep(1)
print('2s')
time.sleep(1)
print('1s')
time.sleep(1)
print('0s')
time.sleep(1)
if __name__ == '__main__':
t1 = MyThread('t1')
t2 = MyThread('t2')
t1.start()
t2.start()
三、线程相关作业
有四个线程,每个线程只打印一个字符,这四个字符分别是 a b c d ,现在要求你做到四个线程顺序打印 a b c d ,且每个线程都打印10次
实现代码:
flag = 0
def th1():
i=0
global flag
while(i<10):
if(flag == 0):
print("a")
i += 1
flag = 1
time.sleep(1)
def th2():
i=0
global flag
while(i<10):
if(flag == 1):
print("b")
i += 1
flag = 2
time.sleep(1)
def th3():
i=0
global flag
while(i<10):
if(flag == 2):
print("c")
i += 1
flag = 3
time.sleep(1)
def th4():
i=0
global flag
while(i<10):
if(flag == 3):
print("d")
i += 1
flag = 0
time.sleep(1)
def main():
try:
_thread.start_new_thread(th1,(),)
_thread.start_new_thread(th2,(),)
_thread.start_new_thread(th3,(),)
_thread.start_new_thread(th4,(),)
except Exception as e:
print("异常",e)
while(1):
pass
main()