Python 多任务 —— 线程

高级编程技巧 学习笔记

一、多任务


        有很多的场景中的事情是同时进行的,比如开车的时候 手和脚共同来驾驶汽车,又比如唱歌跳舞也是同时进行的,再比如边敲代码边听歌。

1.1、多任务的理解

  • 并行: 真的多任务,cpu 大于当前执行的任务
  • 并发: 假的多任务,cpu 小于当前执行的任务

1.2、程序中模拟多任务

import time
import threading


def sing():
    for i in range(3):
        print("正在唱歌....%d" % i)
        time.sleep(1)


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


if __name__ == '__main__':
    # sing()									# 取消注释对比执行结果
    # dance()
    t1 = threading.Thread(target=sing)			# 子线程
    t2 = threading.Thread(target=dance)			# 子线程
    t1.start()
    t2.start()



二、线程


2.1、线程完成多任务

  • 主线程会等到子线程执行结果之后, 主线程才会结束
  1. setDaemon(True) :守护进程,不等子线程结束,主线程继续执行。

  2. join() :等待子线程执行结束,主线程继续执行。

import threading
import time


def demo1():
    for i in range(3):
        print('demo1')


def demo():
    for i in range(5):
        print("hello world")
        time.sleep(1)
        t1 = threading.Thread(target=demo1)
        t1.start()
        t1.join()


if __name__ == '__main__':
    t = threading.Thread(target=demo)

    # 守护线程: 不等子线程结束, 主线程继续执行
    # t.setDaemon(True)

    t.start()

    # 等待子线程执行结束, 主线程继续执行
    t.join()

    print('\nend')

2.2、查看线程数量

  • threading.enumerate() 查看当前线程的数量
import threading
import time


def demo1():
    for i in range(5):
        print("--test1--%d" % i)


def demo2():
    for i in range(5):
        print("--test2--%d" % i)


def main():
    t1 = threading.Thread(target=demo1)
    t2 = threading.Thread(target=demo2)

    t1.start()
    t2.start()

    print(threading.enumerate())
    # [<_MainThread(MainThread, started 13708)>, <Thread(Thread-1, started 6348)>, <Thread(Thread-2, started 14484)>]
    # 一个主线程, 两个子线程


if __name__ == '__main__':
    main()

多次执行上面代码会发现,打印的线程数量个数会发送改变。

这是因为线程的执行顺序是不固定的,所以可以使用 sleep() 延迟更好的进行观察。

import threading
import time


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


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


def main():
    t1 = threading.Thread(target=demo1)
    t2 = threading.Thread(target=demo2)

    t1.start()
    t2.start()

    print(threading.enumerate())

    # # 获取当前程序所有的线程
    # # 线程运行是没有先后顺序的
    # # 可以打印线程数量方便观察
    # while True:
    #     print(threading.enumerate())
    #     if len(threading.enumerate()) <= 1:
    #         break
    #     time.sleep(1)

if __name__ == '__main__':
    main()

2.3、子线程的执行与创建

  • 当调用 Thread 的时候,不会创建线程。

  • 当调用 Thread 创建出来的实例对象的 start 方法的时候,才会创建线程,并且开始运行这个线程。



三、继承 thread 类创建线程


  • 类中一定要有 run() 方法

  • 进程创建依然是 start()

class A(threading.Thread):

    def run(self):
        for i in range(5):
            print(i)


if __name__ == '__main__':
    t = A()
    t.start()



四、多线程共享全局变量(线程间通信)


import threading
import time


def demo1():
    global num
    num += 1
    print("demo1 --- %d" % num)


def demo2():
    print("demo2 --- %d" % num)


def main():
    t1 = threading.Thread(target=demo1)
    t2 = threading.Thread(target=demo2)
    
    t1.start()
    time.sleep(1)							# 不使用 sleep 有可能会先运行 t2 子线程, 则打印出来 num=100
    t2.start()
    time.sleep(1)

    print("main --- %d" % num)


if __name__ == '__main__':
	num = 100
    main()



五、多线程传参


  • threading.Thread() 添加一个 args 参数
import threading
import time


def demo1(num):
    num.append(33)
    print(f"demo1 --- {num}")


def demo2(num):
    print(f"demo2 --- {num}")


def main():
    t1 = threading.Thread(target=demo1, args=(num, ))			# args 需传入元组
    t2 = threading.Thread(target=demo2, args=(num, ))

    t1.start()
    time.sleep(1)
    t2.start()
    time.sleep(1)

    print("main --- %s" % str(num))


if __name__ == '__main__':
	num = [11, 22]
    main()
发布了85 篇原创文章 · 获赞 0 · 访问量 1218

猜你喜欢

转载自blog.csdn.net/qq_43621629/article/details/104099317
今日推荐