美文网首页Python园地
python多线程重入陷阱

python多线程重入陷阱

作者: 小可哥哥V | 来源:发表于2019-04-07 16:13 被阅读0次

多线程使用容易出现重入问题,有时这种重入不易发觉,我们一起看下面这个例子:

import threading
import time


class A:
    def func(self, num):
        self.num = num
        time.sleep(5)
        return self.num


class TestThread(threading.Thread):
    def __init__(self, thread_id, func):
        threading.Thread.__init__(self, name='test')
        self.func = func
        self.thread_id = thread_id

    def run(self):
        num = self.func(self.thread_id)
        print("线程{thread_id}:{num}".format(thread_id=self.thread_id, num=num))


a = A()
th_list = list()
for i in range(5):
    th = TestThread(i, a.func)
    th_list.append(th)

for i in range(5):
    th_list[i].start()

for i in range(5):
    th_list[i].join()

上面这个例子中,多线程类调用了一个类A的成员函数func,而这个func函数会设置A的成员变量num,将线程id传递给func,并且打印返回值,最终的结果如下,发现所有线程中打印出来的数值都是4。

线程1:4
线程0:4
线程2:4
线程3:4
线程4:4

这个的根本原因是:A只有一个实例,虽然传递给各个线程的只是一个成员函数,但这个成员函数可以设置类的成员变量, 这个成员变量因此会被多个线程操纵,造成修改

所以在多线程使用中,谨慎传递类成员函数,因为可以造成变量被覆盖等问题,应当给每个线程实例化自己的对象,调用各个实例自己的成员函数,这样就不会互相干扰。

如下面代码的这种实现方式,就可以解决这个问题:

import threading
import time


class A:
    def func(self, num):
        self.num = num
        time.sleep(5)
        return self.num


class TestThread(threading.Thread):
    def __init__(self, thread_id, Class):
        threading.Thread.__init__(self, name='test')
        a = Class()
        self.func = a.func
        self.thread_id = thread_id

    def run(self):
        num = self.func(self.thread_id)
        print("线程{thread_id}:{num}".format(thread_id=self.thread_id, num=num))


th_list = list()
for i in range(5):
    th = TestThread(i, A)
    th_list.append(th)

for i in range(5):
    th_list[i].start()

for i in range(5):
    th_list[i].join()

线程0:0
线程1:1
线程3:3
线程2:2
线程4:4

相关文章

  • python多线程重入陷阱

    多线程使用容易出现重入问题,有时这种重入不易发觉,我们一起看下面这个例子: 上面这个例子中,多线程类调用了一个类A...

  • 锁 - 可重入 vs 不可重入

    可重入锁 在多线程编程和信号处理过程中,经常会遇到可重入(reentrance)和线程安全(thread-safe...

  • 从ReentrantLock看AQS

    前置知识:多线程同步、ReentrantLock、重入的概念谈到Java的多线程,必然少不了传说中的AQS。那么A...

  • 线程相关问题

    常用并发多线程包 java.util.concurrent synchronized 可重入性 子类可以访问父...

  • 可重入锁

    java多线程编程核心技术2.1.6章-锁重入 在看到这里时,一直理解不来父类子类的可重入锁,一直纠结,如果在父类...

  • redis应用场景之分布式锁

    前言 在单机应用多线程场景下,我们需要使用诸如synchronized、ReentrantLock可重入锁控制对临...

  • 多线程"锁重入"概念

    Java多线程锁重入是指: 在已经获得锁的同步方法或同步代码块内部可以调用锁定对象的其他同步方法, 不需要重新获取...

  • GIL

    谈谈python的GIL、多线程、多进程 最近在看 Python 的多线程,经常我们会听到老手说:“python下...

  • Java并发 | ReentrantLock类

    ReentrantLock可重入锁 在Java多线程中,可以使用synchronized关键字来实现线程之间同步互...

  • Python多线程编程——多线程编程中的加锁机制

    如果大家对Python中的多线程编程不是很了解,推荐大家阅读之前的两篇文章:Python多线程编程——多线程基础介...

网友评论

    本文标题:python多线程重入陷阱

    本文链接:https://www.haomeiwen.com/subject/xbusiqtx.html