python多线程

Posted 时光

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python多线程相关的知识,希望对你有一定的参考价值。

---恢复内容开始---

首先先来看个单线程的例子:

from time import ctime,sleep

def music():
    for i in range(2):
        print("I was listening to music. %s" %ctime())
        sleep(1)

def move():
    for i in range(2):
        print("I was at the movies! %s" %ctime())
        sleep(5)

if __name__ == __main__:
    music()
    move()
    print("all over %s" %ctime())

首先先听了一首music,觉得音乐好听,就用for循环来控制音乐的播放了两次,每首音乐播放需要1秒钟,sleep()来控制音乐播放的时长,

听说有部电影好看,我们就去看,每一场电影需要5秒钟,电影是在太好看了,我们有for循环2次运行结果如下:

我正在听音乐. Sun May 20 12:15:52 2018
我正在听音乐. Sun May 20 12:15:53 2018
你正在看抖音! Sun May 20 12:15:54 2018
你正在看抖音! Sun May 20 12:15:59 2018
all over Sun May 20 12:16:04 2018
[Finished in 12.2s]

通过上边我们看到有两个方法,想到我们可不可以自定义听什么歌,看抖音什么类型的短视频

于是对上面代码加以改造:

from time import ctime,sleep

def music(song):
for i in range(2):
print("我正在听%s音乐. %s" %(song,ctime()))
sleep(1)

def move(tv):
for i in range(2):
print("你正在看抖音%s短视频! %s" %(tv,ctime()))
sleep(5)

if __name__ == ‘__main__‘:
music(‘纸短情长‘)
move(‘吃鸡‘)
print("all over %s" %ctime())

看到了吧 我们加了个参数,运行结果:

我正在听纸短情长音乐. Sun May 20 12:21:24 2018
我正在听纸短情长音乐. Sun May 20 12:21:25 2018
你正在看抖音吃鸡短视频! Sun May 20 12:21:26 2018
你正在看抖音吃鸡短视频! Sun May 20 12:21:31 2018
all over Sun May 20 12:21:36 2018
[Finished in 12.2s]

多线程:体现了一下单线程的使用,那么我们就来看看多线程到底有什么更加强大的功能

from time import ctime, sleep
import threading


def music(song):
    for i in range(2):
        print("I was listening to %s. %s" % (song, ctime()))
        sleep(1)


def move(mymove):
    for i in range(2):
        print("I was at the %s! %s" % (mymove, ctime()))
        sleep(5)

threads = []
th1 = threading.Thread(target=music, args=(一个人走,))
threads.append(th1)
th2 = threading.Thread(target=move, args=(复仇者联盟,))
threads.append(th2)
if __name__ == __main__:
    for t in threads:
        t.setDaemon(True)  # setDaemon(True)将线程声明为
        # 守护线程,必须在start() 方法调用之前设置,如果
        # 不设置为守护线程程序会被无限挂起。子线程启动后,
        # 父线程也继续执行下去,当父线程执行完最后一条语句
        t.start()
    t.join()#程序加了个join()方法,用于等待线程
    # 终止。join()的作用是,在子线程完成运行之前,这个子线
    # 程的父线程将一直被阻塞。
    print("all over %s" % ctime())

首先肯定是要导入threading模块:import threading

 

 

threads = []
th1 = threading.Thread(target=music, args=(‘一个人走‘,))
threads.append(th1)

  创建了threads数组,创建线程th1,使用threading.Thread()方法,在这个方法中调用music方法target=music,args方法对music进行传参。 把创建好的线程t1装到threads数组中。

  接着以同样的方式创建线程th2,并把t2也装到threads数组。

for t in threads:

  t.setDaemon(True)

  t.start()

最后通过for循环遍历数组。(数组被装载了t1和t2两个线程)

 

setDaemon()

  setDaemon(True)将线程声明为守护线程,必须在start() 方法调用之前设置,如果不设置为守护线程程序会被无限挂起。子线程启动后,父线程也继续执行下去,当父线程执行完最后一条语句print "all over %s" %ctime()后,没有等待子线程,直接就退出了,同时子线程也一同结束。

 

start()

开始线程活动。

 运行结果:

I was listening to 一个人走. Sun May 20 12:26:33 2018
I was at the 复仇者联盟! Sun May 20 12:26:33 2018
I was listening to 一个人走. Sun May 20 12:26:34 2018
I was at the 复仇者联盟! Sun May 20 12:26:38 2018
all over Sun May 20 12:26:43 2018
[Finished in 10.3s]

到这里,我们发现如果我有好多个线程,那岂不是我每个线程都要创建一个th~

#!user/bin/env python
# coding=utf-8

from time import ctime, sleep
import threading


def music(song):
    for i in range(2):
        print("I was listening to %s. %s" % (song, ctime()))
        sleep(1)


def move(mymove):
    for i in range(2):
        print("I was at the %s! %s" % (mymove, ctime()))
        sleep(5)


def new_threading(name):
    new_thread = name.split(.)[1]
    if new_thread == mp3:
        music(name)
    else:
        if new_thread == mp4:
            move(name)
        else:
            print(error:The format is not recognized!)

list = [纸短情长.mp3, 复仇者联盟.mp4]
threads = []
file_count = range(len(list))
# 创建线程
for i in file_count:
    t = threading.Thread(target=new_threading, args=(list[i],))
    threads.append(t)
    # 启动线程
if __name__ == __main__:
    for t in file_count:
        threads[t].start()
    for t in file_count:
        threads[t].join()
    print("all over %s" % ctime())

 

我们增加了一个增加线程的方法,只要想 list中添加一个文件,程序会自动为其创建线程

I was listening to 纸短情长.mp3. Sun May 20 12:40:10 2018
I was at the 复仇者联盟.mp4! Sun May 20 12:40:10 2018
I was listening to 纸短情长.mp3. Sun May 20 12:40:11 2018
I was at the 复仇者联盟.mp4! Sun May 20 12:40:15 2018
all over Sun May 20 12:40:20 2018
[Finished in 10.2s]

 

是不是实现了 ,我们继续优化,发现new——threading中有个判断文件扩展名的,然后才调用music和move()

那为什么不用一个方法(也就是一个软件)同时播放音乐和电影呢

#!user/bin/env python
# coding=utf-8

from time import ctime, sleep
import threading


def super_player(file_type,time):
    for i in range(2):
        print("正在播放 %s. %s" % (file_type, ctime()))
        sleep(time)

list ={纸短情长.mp3:2, 复仇者联盟3.mp4:2,人民的名义.wav:4}
threads = []
file_count = range(len(list))
# 创建线程
for file_type,time in list.items():
    t = threading.Thread(target=super_player, args=(file_type,time))
    threads.append(t)
    # 启动线程
if __name__ == __main__:
    for t in file_count:
        # [t].setDaemon(True)  # setDaemon(True)将线程声明为
        # 守护线程,必须在start() 方法调用之前设置,如果
        # 不设置为守护线程程序会被无限挂起。子线程启动后,
        # 父线程也继续执行下去,当父线程执行完最后一条语句
        threads[t].start()
    for t in file_count:
        threads[t].join()
    # t.join()#只对上面的程序加了个join()方法,用于等待线程
    # 终止。join()的作用是,在子线程完成运行之前,这个子线
    # 程的父线程将一直被阻塞。
    print("all over %s" % ctime())

这里我们将list换成字典,定义播放的文件和时长,通过字典的items()方法来循环的取file和time,取到的这两个值用于创建线程。

创建super_player()函数,用于接收file和time,用于确定要播放的文件及时长。运行结果如下:

正在播放 纸短情长.mp3. Sun May 20 12:52:30 2018
正在播放 复仇者联盟3.mp4. Sun May 20 12:52:30 2018
正在播放 人民的名义.wav. Sun May 20 12:52:30 2018
正在播放 纸短情长.mp3. Sun May 20 12:52:32 2018
正在播放 复仇者联盟3.mp4. Sun May 20 12:52:32 2018
正在播放 人民的名义.wav. Sun May 20 12:52:34 2018
all over Sun May 20 12:52:38 2018
[Finished in 8.2s]

 










以上是关于python多线程的主要内容,如果未能解决你的问题,请参考以下文章

[Python3] 043 多线程 简介

python中的多线程和多进程编程

多线程 Thread 线程同步 synchronized

多个用户访问同一段代码

在 Python 多处理进程中运行较慢的 OpenCV 代码片段

线程学习知识点总结