线程及多任务详解(一)

多任务,简单来说就是操作系统可以同时运行多个任务,比如你一边用浏览器浏览着网页,一边使用音乐播放器听歌,还一边修改着word文档,除此之外,还有许多应用程序同时在后台运行着,只是桌面没有显示。

 

对于现在的电脑,多核CPU已比较常见了,即使之前的单核CPU也可以实现多任务,只不过单核CPU中操作系统让各个任务交替执行,事实上比如让任务一执行0.001秒,然后再让任务二执行0.001秒,接着任务三可能也执行0.001秒,由于CPU处理数据执行代码的速度很快,我们肉眼 看起来感觉所有的任务都在一起执行一样。

并发:指的是任务数多于CPU核心数,操作系统通过调度算法,实现将多个任务"一起执行"(事实上总有一些任务没有执行,只是看起来是一起执行而已)

并行:指的是任务数小于CPU核心数,即多个任务真正是同时执行的。

线程

单线程执行:

#coding=utf-8
import time

def sorry():
    print("我错了,对不起...")
    time.sleep(1)


if __name__ == "__main__":
    for i in range(5):
        sorry()

运行结果:

多线程执行:

需要使用threading模块

#coding=utf-8
import time
import threading

def sorry():
    print("我错了,对不起...")
    time.sleep(1)

if __name__ == "__main__":
    for i in range(5):
        t1=threading.Thread(target=sorry)
        t1.start()#启动线程,让线程开始执行

运行结果:

可以明显的看到多线程并发的操作,花费的时间很短,当调用start()方法时,才会真正创建线程,开始执行。

主线程等待子线程执行完毕才结束:

#coding=utf-8
import time
import threading

def sorry():
    print("我错了,对不起...")
    time.sleep(1)


def OK():
    print("OK,原谅你了...")
    time.sleep(1)

if __name__ == "__main__":
    print("-----开始------")
    t1=threading.Thread(target=sorry)
    t2=threading.Thread(target=OK)
    t1.start()
    t2.start()
    time.sleep(5)#延时五秒,主线程会等待子线程全部执行完毕再结束
    print("------结束-------")

输出结果:

 查看线程数量:

#coding=utf-8
import time
import threading

def sing():
    for i in range(5):
        print("正在唱香水有毒%d..."%i)
        time.sleep(1)


def dance():
    for i in range(5):
        print("正在跳芭蕾舞%d..."%i)
        time.sleep(1)


if __name__ == "__main__":
    print("-----开始-------")
    t1=threading.Thread(target=sing)
    t2=threading.Thread(target=dance)
    t1.start()
    t2.start()
    while True:
        length=len(threading.enumerate())#threading.enumerate()可以获取当前运行的线程数
        print("当前运行的线程数为:%d"%length)
        if length<=1:
            break
        time.sleep(1)

运行结果:主线程加上它创建的两个子线程,因此当前运行的线程数为3

 线程执行代码的封装:通过上面的代码可以看出,通过threading模块可以实现多任务的执行,为了使每个线程的封装性更好,使 用threading模块时,往往定义一个新的子类class,只要继承threading.Thread,然后重写run()方法就可以了。

python的threading.Thread类有一个run方法,用于定义线程的功能函数,可以在自己的线程类中覆盖该方法。而创建自己的线程实例后,通过Thread类的start方法,可以启动该线程,交给python虚拟机进行调度,当该线程获得执行的机会时,就会调用run方法执行线程。

#coding=utf-8
import time
import threading

class MyThread(threading.Thread):
    def run(self):
        for i in range(3):
            time.sleep(1)
            msg="I'm" + self.name +"@"+ str(i)
            print(msg)
def test():
    for i in range(5):
        t=MyThread()
        t.start()


if __name__ == "__main__":
    test()

运行结果:

从代码和执行结果我们可以看出,多线程程序的执行顺序是不确定的。当执行到sleep语句时,线程将被阻塞(Blocked),到sleep结束后,线程进入就绪(Runnable)状态,等待调度。而线程调度将自行选择一个线程执行。上面的代码中只能保证每个线程都运行完整个run函数,但是线程的启动顺序、run函数中每次循环的执行顺序都不能确定。

注意:

1.每个线程都默认有一个名字,尽管上述代码中name并未指定name,但python会自动为线程指定一个名字。

2.当线程的run方法结束时,该线程结束。

3.虽然无法控制线程调度程序,但可以通过别的方式影响线程调度的方式。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值