Python-多线程与线程池的基本操作

01创建线程方式1
import threading
import time

# 相关文档
# https://docs.python.org/zh-cn/3/library/threading.html

def loop():
    print(threading.currentThread().getName())
    n = 0
    while n < 5:
        print(n)
        time.sleep(1)
        n += 1


def use_thread():
    print(threading.currentThread().name)
    t = threading.Thread(target=loop, name="now_thread_loop")
    t.start()
    # t.join()
    print("xxx")

if __name__ == '__main__':
    use_thread()
01创建线程方式2
import threading
import time


# 自定义创建线程实现类 实现多线程使用

class myThread(threading.Thread):

    def run(self):
        n = 0

        while n < 5:
            print("当前异步线程的名称是[{0}]".format(threading.currentThread().getName()))
            print(n)
            time.sleep(0.5)
            n += 1


if __name__ == '__main__':
    t=myThread(name="async thread 1")
    t.start()
    print("当前主线程的名称是:[{}]".format(threading.currentThread().getName()))
03多线程并发问题
import threading

"""
测试在没有线程锁的情况下 多线程共同操作同一变量时出现的问题
"""

# 正常执行下 balance 该值应该一直为0
balance = 0


def change_it(n):
    # 如果要在方法内部操作全局变量 外部属性 需要在方法中使用global 变量名 声明一次
    global balance
    balance = balance + n
    balance = balance - n
    if balance != 0:
        print("当前线程[{0}] balance为[{1}]".format(threading.currentThread().getName(), balance))


class changeItClass(threading.Thread):
    def __init__(self, num, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.num = num

    def run(self):
        for i in range(10000000):
            change_it(self.num)


if __name__ == '__main__':
    c1 = changeItClass(num=5, name="aa11")
    c2 = changeItClass(num=8, name="aa22")
    c3 = changeItClass(num=12, name="aa22")
    c1.start()
    c2.start()
    c3.start()
04多线程并发问题解决
import threading

"""
测试在没有线程锁的情况下 多线程共同操作同一变量时出现的问题
"""

# 创建一个线程锁
lock1 = threading.Lock()
# 也可以创建一个RLock 在一个共同资源线程中 可以锁多次 需要注意 使用 threading.Lock.acquire 锁多少次 就需要释放多少次
# 适用范围在相对复杂的业务中 如果只锁一次不够或者一次锁定的代码较多的情况下 可以有选择的进行锁多次
rlock2 = threading.RLock()

# 正常执行下 balance 该值应该一直为0
balance = 0


def change_it(n):
    # 如果要在方法内部操作全局变量 外部属性 需要在方法中使用global 变量名 声明一次
    global balance

    print("11111")
    rlock2.acquire()
    rlock2.acquire()
    print("2222222")
    balance = balance + n
    balance = balance - n
    if balance != 0:
        print("当前线程[{0}] balance为[{1}]".format(threading.currentThread().getName(), balance))

    print("3333333")
    rlock2.release()
    rlock2.release()


class changeItClass(threading.Thread):
    def __init__(self, num, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.num = num

    def run(self):
        for i in range(10000000):
            change_it(self.num)


if __name__ == '__main__':
    c1 = changeItClass(num=5, name="aa11")
    c2 = changeItClass(num=8, name="aa22")
    c3 = changeItClass(num=12, name="aa22")
    c1.start()
    c2.start()
    c3.start()
05使用线程池
import threading
import os
from concurrent.futures.thread import ThreadPoolExecutor

"""
使用线程池 适用对需要使用多个线程运行的业务
通过ThreadPoolExecutor 创建线程池
相关文档:https://docs.python.org/zh-cn/3/library/concurrent.futures.html
"""

# 创建一个线程锁
lock1 = threading.Lock()
# 也可以创建一个RLock 在一个共同资源线程中 可以锁多次 需要注意 使用 threading.Lock.acquire 锁多少次 就需要释放多少次
# 适用范围在相对复杂的业务中 如果只锁一次不够或者一次锁定的代码较多的情况下 可以有选择的进行锁多次
rlock2 = threading.RLock()

# 正常执行下 balance 该值应该一直为0
balance = 0


def change_it(n):
    # 如果要在方法内部操作全局变量 外部属性 需要在方法中使用global 变量名 声明一次
    global balance

    # print("11111")
    # rlock2.acquire()
    print("2222222")
    balance = balance + n
    balance = balance - n
    if balance != 0:
        print("当前线程[{0}] balance为[{1}]".format(threading.currentThread().getName(), balance))
    print("3333333")
    # rlock2.release()


class changeItClass(threading.Thread):
    def __init__(self, num, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.num = num

    def run(self):
        for i in range(10000000):
            change_it(self.num)

if __name__ == '__main__':
    threadPool=ThreadPoolExecutor(max_workers=os.cpu_count()*5)
    threadPool.map(change_it,range(1000000))

版权声明:本文为qq_36871430原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。