python多线程工作原理与实现代码演示

1.什么叫多任务?

        什么叫“多任务”呢?简单地说,就是操作系统可以同时运行多个任务。打个比方,你一边在用浏览器上网,一边在听MP3,一边在用Word赶作业,这就是多任务,至少同时有3个任务正在运行。还有很多任务悄悄地在后台同时运行着,只是桌面上没有显示而已。

2.设么叫线程与进程?

1.进程与线程的描述

进程:是指在系统中正在运行的一个应用程序;
线程:是系统分配处理器时间资源的基本单元(系统内程序执行的最小单元),或者说进程之内独立执行的一个单元。对于操作系统而言,其调度单元是线程。可以理解成一个或多个线程组成了一个进程
2.案例说明
比如在线看视频 其实是 一边从网上下载 一边用播放器播放,从进程来讲就一个(咱们打开的网页) , 其中下载由一个线程管理,播放由一个线程管理.所以这里一个进程有多个线程管理运行的。

3.多任务和多线程,进程之间的关系

  1. 多任务可以由多进程完成,也可以由一个进程内的多线程完成
  2. 进程是由若干线程组成的,一个进程至少有一个线程。

3.python中线程的实现

python中使用threading模块下的Thread类实现线程的应有。

3.1.单线程执行一个程序

#coding=utf-8
import time

def start_Demo1():
    print("i am demo1 .....")
    time.sleep(3)
    print("start_Demo1()单次执行结束")

def start_Demo2():
    print("i am demo2")
    time.sleep(1)
    print("start_Demo2()单次执行结束")

if __name__ == "__main__":
    for i in range(3):
        print("第%d次循环开始:"%(i+1)+time.ctime())
        start_Demo1()
        start_Demo2()
        print("第%d次循环结束:" % (i + 1) + time.ctime())
'''
第1次循环开始:Wed Jul  3 11:33:45 2019
i am demo1 .....
start_Demo1()单次执行结束
i am demo2
start_Demo2()单次执行结束
第1次循环结束:Wed Jul  3 11:33:49 2019
第2次循环开始:Wed Jul  3 11:33:49 2019
i am demo1 .....
start_Demo1()单次执行结束
i am demo2
start_Demo2()单次执行结束
第2次循环结束:Wed Jul  3 11:33:53 2019
第3次循环开始:Wed Jul  3 11:33:53 2019
i am demo1 .....
start_Demo1()单次执行结束
i am demo2
start_Demo2()单次执行结束
第3次循环结束:Wed Jul  3 11:33:57 2019
'''

上面可以看出,通过一个主线程(单线程)执行这个程序,可以发现,程序在单次循环内按顺序执行,先执行完demo1才开始执行demo2的,单次循环耗时4s左右。 然后再多次循环执行,程序花费的时间大概在12s左右,输出有序。

3.2多线程执行同一个程序

import threading
import time

def start_Demo1():
    print("i am demo1 .......")
    time.sleep(3)  #使用多线程并发时,程序不会等待sleep,而是直接执行
    print("start_Demo1()单次执行结束")

def start_Demo2():
    print("i am demo2 .......")
    time.sleep(1)
    print(" start_Demo2()单次执行结束")

if __name__ == "__main__":
    for i in range(3):
        t1 = threading.Thread(target=start_Demo1)
        t2 = threading.Thread(target=start_Demo2)
        print("第%d次循环开始:" % (i + 1) + time.ctime())
        t1.start() #当调用start()时,才会真正的创建线程,并且开始执行
        t2.start()  # 启动线程,即让线程开始执行
        print("第%d次循环结束:" % (i + 1) + time.ctime())

'''
第1次循环开始:Wed Jul  3 11:35:30 2019
i am demo1 .......
i am demo2 .......
第1次循环结束:Wed Jul  3 11:35:30 2019
第2次循环开始:Wed Jul  3 11:35:30 2019
i am demo1 .......
i am demo2 .......
第2次循环结束:Wed Jul  3 11:35:30 2019
第3次循环开始:Wed Jul  3 11:35:30 2019
i am demo1 .......
i am demo2 .......
第3次循环结束:Wed Jul  3 11:35:30 2019
 start_Demo2()单次执行结束
 start_Demo2()单次执行结束
 start_Demo2()单次执行结束
start_Demo1()单次执行结束
start_Demo1()单次执行结束
start_Demo1()单次执行结束
'''

    注意,同一个程序启动多线程执行后,demo1,demo2启动多线程后,程序直接执行下去,不会等待sleep,。尤其要注意函数里的第二个print()打印的时间,是在最后。

3.查看运行中的线程个数

  • threading.enumerate(): 返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前,不包括启动前和终止后的线程
import threading
import time

def test1():
    for i in range(3):
        print("-----test1---%d---" % i)
        time.sleep(1)

def test2():
    for i in range(3):
        print("-----test2---%d---" % i)
        time.sleep(1)

def main():
    t1 = threading.Thread(target=test1)
    t2 = threading.Thread(target=test2)

    t1.start()
    t2.start()

    while True:
        print(threading.enumerate())
        time.sleep(1)

if __name__ == "__main__":
    main()
'''
-----test1---0---
-----test2---0---
[<_MainThread(MainThread, started 10376)>, <Thread(Thread-1, started 6848)>, <Thread(Thread-2, started 7784)>]
-----test2---1---
-----test1---1---
[<_MainThread(MainThread, started 10376)>, <Thread(Thread-1, started 6848)>, <Thread(Thread-2, started 7784)>]
-----test2---2---
[<_MainThread(MainThread, started 10376)>, <Thread(Thread-1, started 6848)>, <Thread(Thread-2, started 7784)>]
-----test1---2---
[<_MainThread(MainThread, started 10376)>, <Thread(Thread-1, started 6848)>, <Thread(Thread-2, started 7784)>]
[<_MainThread(MainThread, started 10376)>]
[<_MainThread(MainThread, started 10376)>]
[<_MainThread(MainThread, started 10376)>]
[<_MainThread(MainThread, started 10376)>]
[<_MainThread(MainThread, started 10376)>]

'''

上面可以看出,t1和t2的具体的执行顺序根据 cpu的调度顺序决定的,不一定谁在前面就谁先执行,可以看出t1t2在执行过程中有三个线程 ,t1t2结束后接只剩下一个主线程了,如果程序结束后,主线程也会关闭。主线程会等待所有的子线程结束后才结束

4.注意下面两个多线程程序的执行结果 

1.将循环放在主线程里,主线程将任务调度给对应子线程执行后,就会直接执行下次主线程循环,而不是等待上一次子线程执行完后才执行下次循环。所以造成第一次循环的子线程还没执行完,在sleep,子线程又开始执行第二次循环。

#1.循环在主线程里
import threading
import time

def start_Demo1():
    print("i am demo1 .......")
    time.sleep(3)  #使用多线程并发时,程序不会等待sleep,而是直接执行
    print("start_Demo1()单次执行结束")

def start_Demo2():
    print("i am demo2 .......")
    time.sleep(1)
    print(" start_Demo2()单次执行结束")

if __name__ == "__main__":
    for i in range(3):
        t1 = threading.Thread(target=start_Demo1)
        t2 = threading.Thread(target=start_Demo2)
        print("第%d次循环开始:" % (i + 1) + time.ctime())
        t1.start() #当调用start()时,才会真正的创建线程,并且开始执行
        t2.start()  # 启动线程,即让线程开始执行
        print("第%d次循环结束:" % (i + 1) + time.ctime())
'''
第1次循环开始:Wed Jul  3 14:00:37 2019
i am demo1 .......
i am demo2 .......
第1次循环结束:Wed Jul  3 14:00:37 2019
第2次循环开始:Wed Jul  3 14:00:37 2019
i am demo1 .......
i am demo2 .......
第2次循环结束:Wed Jul  3 14:00:37 2019
第3次循环开始:Wed Jul  3 14:00:37 2019
i am demo1 .......
i am demo2 .......
第3次循环结束:Wed Jul  3 14:00:37 2019
 start_Demo2()单次执行结束
 start_Demo2()单次执行结束
 start_Demo2()单次执行结束
start_Demo1()单次执行结束
start_Demo1()单次执行结束
start_Demo1()单次执行结束
'''

2.将循环放到子线程里,发现,子线程必须单次执行完(执行sleep,并且执行sleep后的语句后),才会进行下次循环。 

import  threading
import time

def start_Demo1():
    for i in range(3):
        print("i am demo1 .....")
        time.sleep(3)
        print("start_Demo1()单次执行结束")

def start_Demo2():
    for i in range(3):
        print("i am demo2")
        time.sleep(1)
        print("start_Demo2()单次执行结束")

if __name__ == "__main__":
        t1 = threading.Thread(target=start_Demo1)
        t2 = threading.Thread(target=start_Demo2)
        print("第1次循环开始:"  + time.ctime())
        t1.start()  # 当调用start()时,才会真正的创建线程,并且开始执行
        t2.start()  # 启动线程,即让线程开始执行
        print("第1次循环结束:"  + time.ctime())
'''
第1次循环开始:Wed Jul  3 14:05:36 2019
i am demo1 .....
i am demo2
第1次循环结束:Wed Jul  3 14:05:36 2019
start_Demo2()单次执行结束
i am demo2
start_Demo2()单次执行结束
i am demo2
start_Demo1()单次执行结束
i am demo1 .....
start_Demo2()单次执行结束
start_Demo1()单次执行结束
i am demo1 .....
start_Demo1()单次执行结束
'''

统一声明:关于原创博客内容,可能会有部分内容参考自互联网,如有原创链接会声明引用;如找不到原创链接,在此声明如有侵权请联系删除哈。关于转载博客,如有原创链接会声明;如找不到原创链接,在此声明如有侵权请联系删除哈。

发布了248 篇原创文章 · 获赞 1600 · 访问量 267万+

猜你喜欢

转载自blog.csdn.net/qq_26442553/article/details/94552688