Python系列 之 多线程

Python系列 之 多线程,第1张

Python系列 之 多线程

Python 多线程学习
  • 多线程
    • Thread类
    • 继承Thread类
    • ThreadPoolExecutor
    • threading.Lock

多线程 Thread类

利用 Thread类 构造多线程:

import time
import random
import threading
def thread_function(param):
    """线程要执行的函数"""
    # 获取当前线程的名称
    thread_name = threading.current_thread().name
    print(thread_name, "running")
    time.sleep(1)
    print(f"线程名称:{thread_name};函数参数:{param}")
    print(thread_name, "end")
    return thread_name


def run_thread1():
    """方法一:利用Thread类实例对象构建多线程"""
    thread_name = threading.current_thread().name
    print(thread_name, "running")
    thread_list = [threading.Thread(
        target=thread_function, args=(x,), name="thread-%s" % x) for x in range(3)]
    for thread in thread_list:
        thread.start()
    for thread in thread_list:
        thread.join()
    print(thread_name, "end")

if __name__ == '__main__':
    run_thread1()

输出:

MainThread running
thread-0 running
thread-1 running
thread-2 running
线程名称:thread-1;函数参数:1
thread-1 end
线程名称:thread-0;函数参数:0
thread-0 end
线程名称:thread-2;函数参数:2
thread-2 end
MainThread end

继承Thread类

利用继承自Thread类的实例对象构建多线程:继承Thread类,重写Thread类的run方法

import time
import random
import threading
class Thread_Class(threading.Thread):
    """继承Thread类,重写Thread类的run方法 """

    def __init__(self, arg):
        super(Thread_Class, self).__init__()
        self.arg = arg
        self.name = "Thread-%s" % self.arg

    def run(self):
        # 获取当前线程的名称
        thread_name = threading.current_thread().name
        print(thread_name, "running")
        time.sleep(random.random())
        print(f"线程名称:{thread_name};函数参数:{self.arg}")
        print(thread_name, "end")

def run_thread2():
    """方法二:利用继承自Thread类的实例对象构建多线程"""
    thread_name = threading.current_thread().name
    print(thread_name, "running")
    thread_list = [Thread_Class(x) for x in range(3)]
    for thread in thread_list:
        thread.start()
    for thread in thread_list:
        thread.join()
    print(thread_name, "end")
if __name__ == '__main__':
    run_thread2()

输出:

MainThread running
Thread-0 running
Thread-1 running
Thread-2 running
线程名称:Thread-1;函数参数:1
Thread-1 end
线程名称:Thread-2;函数参数:2
Thread-2 end
线程名称:Thread-0;函数参数:0
Thread-0 end
MainThread end

ThreadPoolExecutor

利用ThreadPoolExecutor构建多线程:

import time
import random
from concurrent.futures import ThreadPoolExecutor, as_completed
def thread_function(param):
    """线程要执行的函数"""
    # 获取当前线程的名称
    thread_name = threading.current_thread().name
    print(thread_name, "running")
    time.sleep(1)
    print(f"线程名称:{thread_name};函数参数:{param}")
    print(thread_name, "end")
    return thread_name
    
def run_thread3():
    """方法三:利用ThreadPoolExecutor构建多线程"""
    thread_name = threading.current_thread().name
    print(thread_name, "running")
    with ThreadPoolExecutor(max_workers=3) as executor:
        fu_list = [executor.submit(thread_function, x) for x in range(3)]
        # 得到thread_function函数的返回值
        # for fu in fu_list:
        #     print(fu.result())
        # 得到thread_function函数的返回值
        for fu in as_completed(fu_list):
            print(f"thread_function函数的返回值:{fu.result()}")
    print(thread_name, "end")

if __name__ == '__main__':
    run_thread3()
threading.Lock

线程间变量是共享的;如果多个线程对同一个变量进行修改的话,可能发生意想不到的后果,所以需要在修改变量的时候先拿到锁,并在修改完成后释放锁;

import time
import random
import threading
# 全局变量
ZERO = 0

def chage_list(param):
    # global 关键字声明全局变量
    global ZERO
    # 先加
    ZERO += param
    # 接着 再减去
    ZERO -= param
    # ZERO值不变始终为0
    
def thread_function1(param, lock):
    """
    如果涉及到多个线程之间修改同一变量的时候
    必须加锁
    """
    for i in range(20000):
        # Lock结合with语句
        with lock:
            chage_list(param)
        # 获取锁
        # lock.acquire()
        # try:
        #     chage_list(param)
        # finally:
        #     # 解锁
        #     lock.release()

def run_thread4():
    lock = threading.Lock()
    t_list = []
    for x in range(10):
        t = threading.Thread(target=thread_function1, args=(x, lock))
        t_list.append(t)
        t.start()
    for t in t_list:
        t.join()
    print(ZERO)
if __name__ == '__main__':
    run_thread4()

输出:

0

因为在修改全局变量的时候需要先获取锁才能修改,所以保证了只能同时有一个线程去更改。
以上就是Python中开启多线程的三种方法
如果有什么不对的地方,欢迎指正

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5657732.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-16
下一篇 2022-12-16

发表评论

登录后才能评论

评论列表(0条)

保存