如何在Python中在线程间共享整数

3 投票
1 回答
3808 浏览
提问于 2025-04-19 05:43

我有两个线程:

  • 一个是工作线程,它不停地循环,等待从ssh套接字接收输入
  • 另一个是管理线程,它处理工作线程传来的信息

它们通过一个队列来交流——当有重要信息进来时,工作线程会把它放到队列里,而管理线程则从队列中取出这些信息进行处理。

不过,我希望管理线程也能知道最后一次收到信息的时间——无论这个信息重要与否。

我想的办法是,工作线程可以设置一个整数(比如说),然后管理线程可以读取这个整数。但是,似乎没有线程的基本工具可以支持这个操作。

那么,管理线程直接读取工作线程的实例变量,前提是它不去写这些变量,这样安全吗?还是说这样会导致共享内存的问题?有没有什么办法可以在不把所有杂七杂八的东西放进队列的情况下共享这个状态呢?

1 个回答

4

经理只读取员工的实例变量,前提是没有写入,这样做安全吗?

在CPython中,这是安全的。因为有一个叫做GIL的机制,确保一个线程在读取变量的值时,另一个线程不能同时写入这个变量。简单来说,读取和写入这两个操作都是一个字节码指令,这使得它们是原子的——在执行这条指令时,GIL会被保持住,这样其他线程就不能同时执行。一个操作必须在另一个操作之前或之后完成。只有当两个不同的线程试图对同一个对象进行非原子操作(比如增加一个整数)时,才会出现问题。如果是这种情况,你就需要使用一个threading.Lock(),让两个线程共享这个锁,以便同步对整数的访问。

需要注意的是,字节码的行为(甚至GIL的存在)被认为是实现细节,因此是可能会改变的

CPython的实现细节:字节码是CPython解释器的实现细节!没有保证字节码在不同版本的Python之间不会被添加、删除或更改。

所以,如果你想在所有版本和实现的Python中都绝对安全,使用一个Lock是个好主意,尽管在CPython中现在其实并不必要(而且实际上可能永远都不会需要)。

使用Lock来同步对变量的访问是非常简单的:

lock = threading.Lock()

线程1:

with lock:
   print(shared_int)  # Some read operation
# Lock is release once we leave the with block

线程2:

with lock:
   shared_int = 55 # Some write operation

撰写回答