线程

线程是计算机中被CPU调度的最小单位

线程:轻量级的进程/轻型进程,线程本身创建出来就是为了解决并发问题的,并且他的整体效率比进程要高,但是线程实际上也有一些性能上的限制,管理调度开销

如果你的程序需要数据隔离:多进程,如果你的程序对并发的要求非常高:多线程

python线程模块的选择

Python提供了几个用于多线程编程的模块,包括thread、threading和Queue等。thread和threading模块允许程序员创建和管理线程。thread模块提供了基本的线程和锁的支持,threading提供了更高级别、功能更强的线程管理的功能。Queue模块允许用户创建一个可以用于多个线程之间共享数据的队列数据结构。
  避免使用thread模块,因为更高级别的threading模块更为先进,对线程的支持更为完善,而且使用thread模块里的属性有可能会与threading出现冲突;其次低级别的thread模块的同步原语很少(实际上只有一个),而threading模块则有很多;再者,thread模块中当主线程结束时,所有的线程都会被强制结束掉,没有警告也不会有正常的清除工作,至少threading模块能确保重要的子线程退出后进程才退出。 

  thread模块不支持守护线程,当主线程退出时,所有的子线程不论它们是否还在工作,都会被强行退出。而threading模块支持守护线程,守护线程一般是一个等待客户请求的服务器,如果没有客户提出请求它就在那等着,如果设定一个线程为守护线程,就表示这个线程是不重要的,在进程退出的时候,不用等待这个线程退出。

threading模块

线程的创建Threading.Thread类

import os,time
from threading import Thread
def  func():
    print('start',os.getpid())
    time.sleep(0.1)
    print('end')
t = Thread(target=func)
t.start()
for i  in range(5):
    print('主进程/主线程',os.getpid())

或
from threading import Thread
import time
class Sayhi(Thread):
def __init__(self,name):
super().__init__()
self.name=name
def run(self):
time.sleep(2)
print('%s say hello' % self.name)


if __name__ == '__main__':
t = Sayhi('egon')
t.start()
print('主线程')
View Code

进程与线程的效率对比

import time
from threading import Thread
def func():
    n = 100
    n ** 2
start = time.time()
lst = []
for i in range(100):
    t = Thread(target=func)
    t.start()
    lst.append(t)
for n  in lst:
    n.join()
print('线程:',time.time() -start)

结果:
线程: 0.017000913619995117 #线程的用时


import  time
from multiprocessing import Process
def func():
    t = 100
    t ** 2
if __name__ == '__main__':
    start = time.time()
    lst = []
    for i  in range(100):
        p = Process(target=func)
        p.start()
        lst.append(p)
    for n in lst:
        n.join()
    print('进程:',time.time()-start)

结果:
进程: 5.655323505401611  #进程用时
View Code

线程的数据共享

from threading import Thread
n = 100
def func():
    global n
    n-=10
t = Thread(target=func)
t.start()
t.join()
print(n)

结果:
90

Thread类的其他方法

Thread实例对象的方法
  # isAlive(): 返回线程是否活动的。
  # getName(): 返回线程名。
  # setName(): 设置线程名。

threading模块提供的一些方法:
  # threading.currentThread(): 返回当前的线程变量。
  # threading.enumerate(): 返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前,不包括启动前和终止后的线程。
  # threading.activeCount(): 返回正在运行的线程数量,与len(threading.enumerate())有相同的结果。
from threading import Thread
import threading
from multiprocessing import Process
import os

def work():
    import time
    time.sleep(3)
    print(threading.current_thread().getName())


if __name__ == '__main__':
    #在主进程下开启线程
    t=Thread(target=work)
    t.start()

    print(threading.current_thread().getName())
    print(threading.current_thread()) #主线程
    print(threading.enumerate()) #连同主线程在内有两个运行的线程
    print(threading.active_count())
    print('主线程/主进程')

    '''
    打印结果:
    MainThread
    <_MainThread(MainThread, started 140735268892672)>
    [<_MainThread(MainThread, started 140735268892672)>, <Thread(Thread-1, started 123145307557888)>]
    主线程/主进程
    Thread-1
    '''

代码示例

守护线程

import time
from threading import Thread

def func():
    while True:
        print('in func')
        time.sleep(0.5)

def func2():
    print('start func2')
    time.sleep(10)
    print('end func2')

Thread(target=func2).start()
t = Thread(target=func)
t.setDaemon(True)
t.start()
print('主线程')
time.sleep(2)
print('主线程结束')

 

原文地址:https://www.cnblogs.com/wanglan/p/10103041.html