threading和_thread创建多线程

本篇可看文字,别看代码,代码太多,看着有复用的就拿走
具体的来源;太多文字描述了,最后还有糖果机和生产队列实例,实在弄不清楚应用的地方

threading模块多线程创建的两种方法

首先他有两种创建多线程的方法,一般都是选threading模块,而另外一种是_thread模块,是为了延续python中的thread模块
threading模块创建多线程有两个方法,第一个是使用threading.Thread类,想该类中传入函数(关键字target),还有函数的参数(关键字args),就算函数没有参数也必须写上空元组。然后再把该类传入的对象赋值给一个变量该变量使用start()函数启动线程,若是多个函数,可使用join()函数()确保两个线程结束运行。

使用threading.Thread类

import threading
'''
在threading模块中,除包含"_thread"模块中的所有方法之外,还提供了如下的核心方法
.currentThread():返回当前的Thread对象,这是一个线程变量
.enumerate:返回一个包含正在运行的线程的列表
.activeCount():返回正在运行的线程数量
.main_thread():返回主thread对象。正常情况下,主线程是从python解释器中启动的线程
settrace(func):为所有从threading模块启动的线程设置一个跟踪方法。在每个线程的run()方法调用之前,func将传递给sys.settrace()
.setprofile(func):为所有从threading模块启动的线程设置一个profile()方法
还提供.TIMEOUT_MAX,该方法表示阻塞方法允许等待的最长时限,设置超过此值的超时将会引发OverflowError
'''
from time import sleep, ctime
# 线程函数,index表示整数类型的索引,sec表示休眠时间,单位:秒
def fun(index, sec):
    print('开始执行', index, ' 时间:', ctime())
    # 休眠sec秒
    sleep(sec)
    print('结束执行', index, '时间:', ctime())
def main():
    # 创建第1个Thread对象,通过target关键字参数指定线程函数fun,传入索引10和休眠时间(4秒)
    thread1 = threading.Thread(target=fun,
            args=(10, 4))
    # 启动第1个线程
    thread1.start()
    # 创建第2个Thread对象,通过target关键字参数指定线程函数fun,传入索引20和休眠时间(2秒)
    thread2 = threading.Thread(target=fun,
            args=(20, 2))
    # 启动第2个线程
    thread2.start()
    # 等待第1个线程函数执行完毕
    thread1.join()
    # 等待第2个线程函数执行完毕
    thread2.join()

if __name__ == '__main__':
    main()

另外一种方式是类的构造(threading.Thread)

重写该类中的run()方法
但具体调用的函数命名也就必须为run()了

import threading
from time import sleep, ctime


# 从Thread类派生的子类
class MyThread(threading.Thread):
    # 重写父类的构造方法,其中func是线程函数,args是传入线程函数的参数,name是线程名
    def __init__(self, func, args, name=''):
        # 调用父类的构造方法,并传入相应的参数值
        super().__init__(target=func, name=name,
                         args=args)

    # 重写父类的run方法
    def run(self):
        self._target(*self._args)


# 线程函数
def fun(index, sec):
    print('开始执行', index, '时间:', ctime())
    # 休眠sec秒
    sleep(sec)
    print('执行完毕', index, '时间:', ctime())


def main():
    print('开始:', ctime())
    # 创建第1个线程,并指定线程名为“线程1”
    thread1 = MyThread(fun, (10, 4), '线程1')
    # 创建第2个线程,并指定线程名为“线程2”
    thread2 = MyThread(fun, (20, 2), '线程2')
    # 开启第1个线程
    thread1.start()
    # 开启第2个线程
    thread2.start()
    # 输出第1个线程的名字
    print(thread1.name)
    # 输出第2个线程的名字
    print(thread2.name)
    # 等待第1个线程结束
    thread1.join()
    # 等待第2个线程结束
    thread2.join()

    print('结束:', ctime())
if __name__ == '__main__':
    main()

_thread模块有的方法,threading模块都有

其实threading是在_thread基础上建立的,_thread创建多线程虽然也是使用类对象,但并不是使用start()函数启动线程,而是使用start_new_thread()函数启动线程,具体启用多少个线程可以使用for循环

import random
from time import sleep
import _thread as thread
# 线程函数,其中a和b是通过start_new_thread函数传入的参数
def fun(a,b):
    print(a,b)
    # 随机休眠一个的时间(1到4秒)
    sleep(random.randint(1,5))
    '''
    print()函数的执行结果;可以得知该多线程是无序的
    1 a
4 aaaa    
2 aa      
5 aaaaa   
8 aaaaaaaa
6 aaaaaa  
3 aaa     
7 aaaaaaa 
    '''
#  启动8个线程
for i in range(8):
    # 为每一个线程函数传入2个参数值
    thread.start_new_thread(fun, (i + 1,'a' * (i + 1)))
# 通过从终端输入一个字符串的方式让程序暂停
input() # 去掉该input函数,就不会将print()函数的内容打印在终端

另外一个实例

import _thread as thread
'''
thread原本是python2中的模块,在python3中被threading替换,但为了兼容python2的程序,在
python3中将thread模块重命名为"_thread"
'''
from time import sleep, ctime
def fun1():
    print('开始运行fun1:', ctime())
    # 休眠4秒
    sleep(4)
    print('fun1运行结束:', ctime())

def fun2():
    print('开始运行fun2:', ctime())
    # 休眠2秒
    sleep(2)
    print('fun2运行结束:', ctime())

def main():
    print('开始运行时间:', ctime())
    # 启动一个线程运行fun1函数
    thread.start_new_thread(fun1, ())
    '''
    start_new_thread()函数的第二个参数必须是元组,第一个参数必须是线程函数
    '''
    # 启动一个线程运行fun2函数
    thread.start_new_thread(fun2, ())
    # 休眠6秒
    sleep(6)
    print('结束运行时间:', ctime())

if __name__ == '__main__':
    main()
'''
在锁定对象_thread中包含如下方法
lock.acquire(waitflag=1,timeout=-1):里面的是参数值设置,如果设置了第一个参数,那么将依赖该参数的值:如果该参数为0,则
锁不等待且立即返回;不为0,则锁无条件的等待。
第二个参数的值若大于0,则指定等待的最大秒数,若参数为负数,则表示永久等待,如果第一个参数为0,则无法设置第二个参数。(一般情况下都不设置参数,一次仅一个线程能获取锁)
lock.release():释放锁。锁必须早已获取,但不一定由同一线程获取
lock.locked():返回锁的状态,True表示以被某个线程获取,False表示没有被某个线程获取
'''
posted @ 2021-12-15 16:42  索匣  阅读(269)  评论(0编辑  收藏  举报