欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

关于python的单线程和多线程

程序员文章站 2022-05-02 16:58:50
...

单线程

比如两件事,要相继执行,而不是一起执行


'''学习一下单线程和多线程的问题'''

from time import ctime,sleep
'''单线程'''
print('单线程开始:')
def music_single(name):
    for i in range(2):
        print('i was listening to music %s. %s' %(name,ctime()))
        sleep(1)
def move_single(name):
    for i in range(2):
        print('i was at the movies %s! %s' %(name,ctime()))
        sleep(5)
if __name__=="__main__":
    music_single(u'夜空中最亮的星')
    move_single(u'谍影重重')
    print('all over %s' %ctime())

输出结果:

单线程开始:
i was listening to music 夜空中最亮的星. Mon Aug 27 21:24:03 2018
i was listening to music 夜空中最亮的星. Mon Aug 27 21:24:04 2018
i was at the movies 谍影重重! Mon Aug 27 21:24:05 2018
i was at the movies 谍影重重! Mon Aug 27 21:24:10 2018
all over Mon Aug 27 21:24:15 2018

多线程

即边听歌边看电影,python中有thread和threading用来实现多线程,在这里使用threading。

'''多线程'''
print('****************')
print('多线程开始:')
from time import ctime,sleep
import threading

def music_mutil(name):
    for i in range(2):
        print('i was listening to music %s. %s' %(name,ctime()))
        sleep(1)
def move_mutil(name):
    for i in range(2):
        print('i was at the movies %s! %s' %(name,ctime()))
        sleep(5)

threads=[]
t1=threading.Thread(target=music_mutil,args=(u'夜空中最亮的星',)) # 创建线程t1
threads.append(t1)
t2=threading.Thread(target=move_mutil,args=(u'谍影重重',)) # 创建线程t2
threads.append(t2)

if __name__=='__main__':
    for t in threads: # 遍历线程数组
        t.setDaemon(True) # 将线程声明为守护线程,必须在start()之前设置,如果不设置为守护线程,那么程序会被无限挂起。
        t.start() # 开始线程    
    t.join()
    print('all over %s' %ctime())

输出结果:


****************
多线程开始:
i was listening to music 夜空中最亮的星. Mon Aug 27 21:24:15 2018
i was at the movies 谍影重重! Mon Aug 27 21:24:15 2018
i was listening to music 夜空中最亮的星. Mon Aug 27 21:24:16 2018
i was at the movies 谍影重重! Mon Aug 27 21:24:20 2018
all over Mon Aug 27 21:24:25 2018

注意:
倘若没有join()语句,那么输出结果为

****************
多线程开始:
i was listening to music 夜空中最亮的星. Mon Aug 27 21:27:29 2018
i was at the movies 谍影重重! Mon Aug 27 21:27:29 2018
all over Mon Aug 27 21:27:29 2018

分析:
以上,从运行结果看,子线程(music_mutil,move_mutil)和主线程(print(all over %s) %ctime())一起启动,但是主线程结束导致子线程也终止。在这里可以在主线程前面加上t.join(),其作用是在子线程完成运行之前,子线程的父线程将一直被阻塞。注意,join()的位置是在for循环外的,也就是说必须等待for循环里的两个进程都结束后,才去执行主进程。

多线程进阶

重写一下代码,写一个player,根据文件类型来选择操作。

from time import ctime,sleep
import threading

def music(name):
    for i in range(2):
        print('start playing %s. %s' %(name,ctime()))
        sleep(2)

def move(name):
    for i in range(2):
        print('start playing %s. %s' %(name,ctime()))
        sleep(5)

def player(func):
    rc=func.split('.')[1]
    if rc=='mp3':
        music(func)
    else:
        if rc=='mp4':
            move(func)
        else:
            print('error type of file!')

alist=['夜空中最亮的星.mp3','谍影重重.mp4']
length=len(alist)
threads=[]
# 创建线程
for i in range(length):
    t=threading.Thread(target=player,args=(alist[i],))
    threads.append(t)
if __name__=='__main__':
    # 启动线程
    for i in range(length):
        threads[i].start()
    for i in range(length):
        threads[i].join()

    # 主线程
    print('all over at %s' %(ctime()))

输出:

start playing 夜空中最亮的星.mp3. Mon Aug 27 21:52:50 2018
start playing 谍影重重.mp4. Mon Aug 27 21:52:50 2018
start playing 夜空中最亮的星.mp3. Mon Aug 27 21:52:52 2018
start playing 谍影重重.mp4. Mon Aug 27 21:52:55 2018
all over at Mon Aug 27 21:53:00 2018

继续修改:

from time import ctime,sleep
import threading

def super_player(name,time0):
    for i in range(2):
        print('now we are playing %s. %s' %(name,ctime()))
        sleep(time0)
# 
alist={'飞鸟.mp3':3,'阿凡达.mp4':4,'我和你.mp3':4}

threads=[]
files=range(len(alist))

# 创建线程
for file,time in alist.items():
    t=threading.Thread(target=super_player,args=(file,time))
    threads.append(t)

if __name__=='__main__':
    # 启动线程
    for i in files:
        threads[i].start()
    for i in files:
        threads[i].join()
    # 主线程
    print('end: %s' %ctime())

输出:

now we are playing 飞鸟.mp3. Mon Aug 27 21:57:02 2018
now we are playing 阿凡达.mp4. Mon Aug 27 21:57:02 2018
now we are playing 我和你.mp3. Mon Aug 27 21:57:02 2018
now we are playing 飞鸟.mp3. Mon Aug 27 21:57:05 2018
now we are playing 我和你.mp3. Mon Aug 27 21:57:06 2018
now we are playing 阿凡达.mp4. Mon Aug 27 21:57:06 2018
end: Mon Aug 27 21:57:10 2018

继续创建:

'''创建自己的多线程类'''

#coding=utf-8
import threading
from time import sleep,ctime

class MyThread(threading.Thread):
    def __init__(self,func,args,name=''):
        threading.Thread.__init__(self)
        self.name=name
        self.func=func
        self.args=args
    def run(self):
        # apply(self.func,self.args) # python2的用法
        self.func(*self.args) # python3没有了apply()的全局用法。用self.func(*self.args)。

def super_play(file,time):
    for i in range(2):
        print('start playing: %s! %s' %(file,ctime()))
        sleep(time)

alist={'红日.mp3':3,'阿凡达.mp4':5}

# 创建线程
threads=[]
files=range(len(alist))

for k,v in alist.items():
    t=MyThread(super_play,(k,v),super_play.__name__)
    threads.append(t)

if __name__=='__main__':
    # 启动线程
    for i in files:
        threads[i].start()
    for i in files:
        threads[i].join()
    # 主线程
    print('end: %s' %ctime())

输出:

start playing: 红日.mp3! Mon Aug 27 21:58:48 2018
start playing: 阿凡达.mp4! Mon Aug 27 21:58:48 2018
start playing: 红日.mp3! Mon Aug 27 21:58:51 2018
start playing: 阿凡达.mp4! Mon Aug 27 21:58:53 2018
end: Mon Aug 27 21:58:58 2018