python多线程信息提示

本文探讨了Python多线程中的关键概念,包括设置时间提醒、设置守护线程(daemon)、如何优雅地结束子线程并结束主线程、使用`ThreadPoolExecutor`启动多线程、理解`with`语句在加锁中的应用,以及介绍了生产者消费者模型和多进程读写锁的实现,阐述了在并发场景下确保数据一致性的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

时间提醒

import threading
import logging
import time


def thread_function(name):
    logging.info("Thread %s starting", name)
    time.sleep(2000)
    logging.info("Thread %s finishing", name)


if __name__ == "__main__":
    format = "%(asctime)s: %(message)s"
    logging.basicConfig(format=format, level=logging.INFO, datefmt="%H:%M:%S")
    logging.info("Main : before creating thread")
    x = threading.Thread(target=thread_function, args=(1,))
    logging.info("Main : wait for the thread to finish")
    logging.info("Main : all done")

daemon

含有daemon标识的线程,当程序结束的时候,线程强制结束

import threading
import logging
import time


def thread_function(name):
    logging.info("Thread %s starting", name)
    time.sleep(2)
    logging.info("Thread %s finishing", name)


if __name__ == "__main__":
    format = "%(asctime)s: %(message)s"
    logging.basicConfig(format=format, level=logging.INFO, datefmt="%H:%M:%S")
    logging.info("Main : before creating thread")
    x = threading.Thread(target=thread_function, args=(1,),  daemon=True)
    x.start()
    logging.info("Main : wait for the thread to finish")
    logging.info("Main : all done")

结束子线程后结束主线程

使用join

import threading
import logging
import time


def thread_function(name):
    logging.info("Thread %s starting", name)
    time.sleep(2)
    logging.info("Thread %s finishing", name)


if __name__ == "__main__":
    format = "%(asctime)s: %(message)s"
    logging.basicConfig(format=format, level=logging.INFO, datefmt="%H:%M:%S")
    logging.info("Main : before creating thread")
    x = threading.Thread(target=thread_function, args=(1,),  daemon=True)
    x.start()
    logging.info("Main : wait for the thread to finish")
    x.join() # 加上这一句会强制等待所有子线程结束后结束主线程
    logging.info("Main : all done")

启动多线程的方法

ThreadPoolExecutor头文件

import concurrent.futures

实际调用

with concurrent.futures.ThreadPoolExecutor(max_workers=3) as executor:
	executor.map(thread_function, range(3))

加锁(包含对with 语句的理解)

在这里插入图片描述

生产者消费者线程

快的是生产者(要理发的人),慢的是消费者(理发师)
生产者排队,将一个随机信息发给消费者

import logging
import threading
import concurrent.futures
import time
import random

SENTINEL = object()

class Pipeline(object):
    def __init__(self):
        self.message = 0
        self.producer_lock = threading.Lock()
        self.consumer_lock = threading.Lock()
        self.consumer_lock.acquire()

    def get_message(self, name):
        logging.debug("%s: about to acquire getlock", name)
        self.consumer_lock.acquire()
        logging.debug("%s: have getlock", name)
        message = self.message
        logging.debug("%s: about to release setlock", name)
        self.producer_lock.release()
        logging.debug("%s: setlock released", name)
        return message

    def set_message(self, message, name):
        logging.debug("%s: about to acquire setlock", name)
        self.producer_lock.acquire()
        logging.debug("%s: have setlock", name)
        self.message = message
        logging.debug("%s: about to release getlock", name)
        self.consumer_lock.release()
        logging.debug("%s: have released getlock", name)


def producer(pipeline):
    '''pretend we are getting a message from the network'''
    for index in range(10):
        message = random.randint(1, 101)
        logging.info("Producer got message: %s", message)
        pipeline.set_message(message, "Producer")

    # send a sentinel message to tell consumer we're done
    pipeline.set_message(SENTINEL, "Producer")


def consumer(pipeline):
    message = 0
    while message is not SENTINEL:
        message = pipeline.get_message("Consumer")
        if message is not SENTINEL:
            logging.info("Consumer storing message %s", message)



if __name__ == '__main__':
    format = "%(asctime)s: %(message)s"
    logging.getLogger().setLevel(logging.DEBUG)
    logging.basicConfig(format=format, level=logging.INFO, datefmt="%H:%M:%S")

    pipeline = Pipeline()
    with concurrent.futures.ThreadPoolExecutor(max_workers=2) as executor:
        executor.submit(producer, pipeline)
        executor.submit(consumer, pipeline)

多进程读写锁

写的时候不能有人读或者写,读的时候没人写就行

import logging
import threading
import concurrent.futures
import time
import random

SENTINEL = object()


class Pipeline(object):
    def __init__(self):
        self.message = 0
        self.producer_lock = threading.Lock()
        self.consumer_lock = threading.Lock()

    def get_message(self, name):
        while True:
            if not self.producer_lock.locked():
                logging.debug("%s: no write, begin to read", name)
                self.consumer_lock.acquire()
                logging.debug("%s: have get readlock", name)
                message = self.message
                logging.debug("%s: have get the message, about to release readlock", name)
                self.consumer_lock.release()
                break

        return message

    def set_message(self, message, name):
        while True:
            if not self.consumer_lock.locked() and not self.producer_lock.locked():
                logging.debug("%s: no write and read, begin to write", name)
                self.producer_lock.acquire()
                logging.debug("%s: get setlock", name)
                self.message = message
                logging.debug("%s: setover about to release setlock", name)
                self.producer_lock.release()
                break
        return



def producer(pipeline):
    '''pretend we are getting a message from the network'''
    for index in range(10):
        message = random.randint(1, 101)
        logging.info("Producer got message: %s", message)
        pipeline.set_message(message, "Producer")

    # send a sentinel message to tell consumer we're done
    pipeline.set_message(SENTINEL, "Producer")


def consumer(pipeline):
    message = 0
    while message is not SENTINEL:
        message = pipeline.get_message("Consumer")
        if message is not SENTINEL:
            logging.info("Consumer storing message %s", message)


if __name__ == '__main__':
    format = "%(asctime)s: %(message)s"
    logging.getLogger().setLevel(logging.DEBUG)
    logging.basicConfig(format=format, level=logging.INFO, datefmt="%H:%M:%S")

    pipeline = Pipeline()
    with concurrent.futures.ThreadPoolExecutor(max_workers=3) as executor:
        executor.submit(producer, pipeline)
        executor.submit(producer, pipeline)
        executor.submit(consumer, pipeline)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值