python中多线程threading

文章介绍了Python的threading模块,包括active_count(),current_thread(),get_ident()等函数,以及线程的创建、启动、join()、守护线程的概念。同时,文章还讲解了如何创建类的成员函数作为线程,并展示了如何通过设置守护线程确保程序退出。另外,文章提到了多线程队列Queue,包括其FIFO特性、put_nowait(),get_nowait(),full(),empty(),qsize()等方法,以及task_done()和join()在队列操作中的作用。
创建线程
import threading

threading中重要函数

active_count()

返回当前存活的线程类 Thread 对象。

current_thread()

返回当前对应调用者的控制线程的 Thread 对象。

get_ident()

返回当前线程的 “线程标识符”。它是一个非零的整数。

enumerate()

以列表形式返回当前所有存活的 Thread 对象。

main_thread()

返回主 Thread 对象。一般情况下,主线程是Python解释器开始时创建的线程。

settrace(func)

为所有 threading 模块开始的线程设置追踪函数。在每个线程的 run() 方法被调用前,func 会被传递给 sys.settrace() 。

setprofile(func)

为所有 threading 模块开始的线程设置性能测试函数。在每个线程的 run() 方法被调用前,func 会被传递给 sys.setprofile() 。

stack_size([size])

返回创建线程时用的堆栈大小。

重要功能
  • run()
    用以表示线程活动的方法

  • start()
    启动线程活动

  • join([time])
    等待至线程中止

  • isAlive()
    返回线程是否活动

  • getName()
    返回线程名

  • setName()
    设置线程名

守护线程

另外一个重要的入口参数是daemon,它的作用是设置线程是否为守护线程(后台线程)。守护线程有一个重要的特点是主线程(例子的main()线程)退出时,守护线程不管怎样都要跟主线程一起退出。

守护线程的目的与作用:

所以,我的理解是:当创建的子线程是无限循环的话,就应该设置为守护线程。随着主线程的退出,子线程被强制退出,保证了整个python程序正常地,完整地退出。

类下线程

将类的成员函数当做线程启动:

由于线程共享进程的资源,所以修改类中成员变量,可以影响到线程中对该成员变量的使用,所以不需要重新启动线程。

import os
from pathlib import Path
from time import sleep, time
from threading import Thread
from colorama import init, Fore, Back, Style

if "PYCHARM_HOSTED" in os.environ:
    convert = False
    strip = False
else:
    convert = None
    strip = None

init(convert=convert, strip=strip)

cur_pdir = Path(os.path.dirname(os.path.abspath(__file__)))
print("cur_pdir: ", cur_pdir)


class SomeClass(object):
    def __init__(self, flag_polling=False):

        # 轮询标志位 #
        self.flag_polling = flag_polling

        # 启动守护线程 #
        self.start()

    def start(self):
        """
        开机即开启
        :return:
        """
        # 串口轮询线程
        self.thread = self.openThread(self.get_status, args=())

    def get_status(self):
        """
        串口线程
        :return:
        """
        while True:
            print(">>>")
            print("flag_polling: ", self.flag_polling)
            if self.flag_polling:
                print(Fore.MAGENTA+"start to polling"+Style.RESET_ALL)
            print()
            sleep(0.1)

    @staticmethod
    def openThread(func, args=()):
        thread = Thread(target=func, args=args)
        thread.setDaemon(True)
        thread.start()
        return thread


if __name__ == '__main__':

    sc = SomeClass()

    index = 0
    while True:
        sleep(0.5)

        if index == 10 * 5:
            print(Back.CYAN+"i am going to change flag"+Style.RESET_ALL)
            sc.flag_polling = True

        index = index + 1
多线程队列Queue
概述

导入队列:

from queue import Queue

Queue队列遵循的是先进先出。

queue.Queue是进程内非阻塞队列,用于进程内的各函数模块或线程间通信。

q.put_nowait()

q.put_nowait()方法可以无阻碍地向队列中添加内容,如果队列已满则会立即报错,不会等待(即不会发生阻塞)。

q.get_nowait()

q.get_nowait()方法可以无阻碍地从队列中取出内容,如果队列是空的则也会直接报错,不会等待。

q.full()

判断队列是否是满的

q.empty()

判断队列是否是空的

q.qsize()

返回队列的大小

Queue提供了一个基本的FIFO容器,使用方法很简单Queue(maxsize=0),maxsize是个整数,指明了队列中能存放的数据个数的上限。一旦达到上限,插入会导致阻塞,直到队列中的数据被消费掉。如果maxsize小于或者等于0,队列大小没有限制。

q.clear()

清空队列

task_done()

意味着之前入队的一个任务已经完成。由队列的消费者线程调用。每一个get()调用得到一个任务,接下来的task_done()调用告诉队列该任务已经处理完毕。

如果当前一个join()正在阻塞,它将在队列中的所有任务都处理完时恢复执行(即每一个由put()调用入队的任务都有一个对应的task_done()调用)。

join()

阻塞调用线程,直到队列中的所有任务被处理掉。

只要有数据被加入队列,未完成的任务数就会增加。当消费者线程调用task_done()(意味着有消费者取得任务并完成任务),未完成的任务数就会减少。当未完成的任务数降到0,join()解除阻塞。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wugou2014

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值