python:并发编程(九)

前言

本文将和大家一起探讨python的多线程并发编程(下篇),使用内置基本库threading来实现并发,先通过官方来简单使用这个模块。先打好基础,能够有个基本的用法与认知,后续文章,我们再进行详细使用。

本文为python并发编程的第九篇,上一篇文章地址如下:

python:并发编程(八)_Lion King的博客-CSDN博客

下一篇文章地址如下:

python:并发编程(十)_Lion King的博客-CSDN博客

一、实战

1、创建两个线程,一个线程打印偶数,另一个线程打印奇数,要求按顺序打印

import threading

# 定义一个全局变量,用于控制打印的数字
num = 0

# 创建一个锁对象
lock = threading.Lock()

# 偶数线程函数
def print_even():
    global num
    while num < 10:
        # 获取锁
        lock.acquire()
        if num % 2 == 0:
            print("Even:", num)
            num += 1
        # 释放锁
        lock.release()

# 奇数线程函数
def print_odd():
    global num
    while num < 10:
        # 获取锁
        lock.acquire()
        if num % 2 != 0:
            print("Odd:", num)
            num += 1
        # 释放锁
        lock.release()

# 创建偶数线程
even_thread = threading.Thread(target=print_even)

# 创建奇数线程
odd_thread = threading.Thread(target=print_odd)

# 启动线程
even_thread.start()
odd_thread.start()

# 等待线程结束
even_thread.join()
odd_thread.join()

这个程序创建了两个线程,一个线程负责打印偶数,另一个线程负责打印奇数。使用全局变量num来控制打印的数字,初始值为0。通过获取锁来保证只有一个线程能够打印数字,并在打印后释放锁,以实现按顺序打印偶数和奇数。最后,使用join()方法等待两个线程执行完成。

运行这个程序,你将会看到按顺序打印出0到9的偶数和奇数。

2、创建三个线程,每个线程打印出一个字母(A、B、C),循环打印10次,要求按顺序打印ABCABC...

import threading

# 创建一个信号量,初始值为0
semaphore_A = threading.Semaphore(1)
semaphore_B = threading.Semaphore(0)
semaphore_C = threading.Semaphore(0)

# 打印A的线程函数
def print_A():
    for _ in range(10):
        # 获取A的信号量,允许打印A
        semaphore_A.acquire()
        print("A", end="")
        # 发送信号量给B,允许打印B
        semaphore_B.release()

# 打印B的线程函数
def print_B():
    for _ in range(10):
        # 获取B的信号量,允许打印B
        semaphore_B.acquire()
        print("B", end="")
        # 发送信号量给C,允许打印C
        semaphore_C.release()

# 打印C的线程函数
def print_C():
    for _ in range(10):
        # 获取C的信号量,允许打印C
        semaphore_C.acquire()
        print("C", end="")
        # 发送信号量给A,允许打印A
        semaphore_A.release()

# 创建三个线程
thread_A = threading.Thread(target=print_A)
thread_B = threading.Thread(target=print_B)
thread_C = threading.Thread(target=print_C)

# 启动线程
thread_A.start()
thread_B.start()
thread_C.start()

# 等待线程结束
thread_A.join()
thread_B.join()
thread_C.join()

这个程序创建了三个线程,分别用于打印字母A、B和C。通过使用信号量来控制线程的执行顺序。初始时,A线程获得信号量semaphore_A,允许打印A,然后它将信号量semaphore_B释放,允许B线程执行。B线程打印B后,释放信号量semaphore_C,允许C线程执行。C线程打印C后,释放信号量semaphore_A,允许A线程执行,从而形成ABCABC...的循环打印。

运行这个程序,你将会看到按顺序循环打印出ABCABC...,每个字母重复打印10次。

3、创建两个线程,一个线程用于输入数字,另一个线程用于计算数字的平方,并将结果输出

import threading
import queue

# 用于输入数字的线程函数
def input_number():
    while True:
        number = input("请输入一个数字(输入exit退出):")
        if number == "exit":
            break
        else:
            # 将输入的数字转换为整数,并发送给计算线程
            calculation_thread.queue.put(int(number))

# 用于计算数字平方并输出结果的线程函数
def calculate_square():
    while True:
        number = calculation_thread.queue.get()
        square = number ** 2
        print(f"{number} 的平方是 {square}")

# 创建一个线程间通信的队列
calculation_thread = threading.Thread(target=calculate_square)
calculation_thread.queue = queue.Queue()

# 创建输入数字的线程
input_thread = threading.Thread(target=input_number)

# 启动两个线程
calculation_thread.start()
input_thread.start()

# 等待输入线程结束
input_thread.join()

# 清空队列中的剩余元素
while not calculation_thread.queue.empty():
    number = calculation_thread.queue.get()
    square = number ** 2
    print(f"{number} 的平方是 {square}")

# 等待计算线程结束
calculation_thread.join()

这个程序创建了两个线程,一个用于输入数字,另一个用于计算数字的平方并输出结果。输入线程通过用户输入数字,并将其转换为整数后发送给计算线程。计算线程从队列中获取数字,并计算其平方后输出结果。当用户输入"exit"时,输入线程退出,然后程序等待队列中剩余的计算任务完成,并输出结果。

运行这个程序,你可以多次输入数字,程序将会实时计算并输出数字的平方。当你输入"exit"时,程序会等待队列中的剩余计算任务完成,并输出结果。

二、threading模块主要功能 

1、线程的创建

使用Thread类创建线程对象,将要执行的函数作为参数传递给线程对象的target参数。

2、启动线程

使用线程对象的start方法启动线程,该方法会自动调用线程函数。

3、线程同步

使用锁、条件、信号量等同步机制来控制线程的执行顺序和访问共享资源的安全性。

4、线程间通信

可以使用队列、事件、管道等机制实现线程间的通信,以便在不同线程之间传递数据或控制信息。

5、线程的终止

线程可以通过设置标志位或调用Thread类的stop方法来终止线程的执行。然而,直接终止线程可能导致资源泄漏或数据不一致,因此最好通过合理的设计和协调使线程正常退出。

6、线程的等待

使用join方法可以等待线程执行完成,主线程可以调用线程对象的join方法来等待子线程的结束。

7、线程的优先级

可以使用Thread类的setDaemon方法设置线程的优先级。

8、线程的异常处理

可以使用try-except语句捕获线程执行过程中可能抛出的异常,确保程序的健壮性。

9、线程的命名

可以给线程对象设置一个有意义的名称,方便调试和识别不同的线程。

10、线程的数量

在创建线程时要考虑系统的资源限制,过多的线程可能会导致资源竞争和性能下降。

你可能感兴趣的:(python,python)