是+ = 1线程安全 [英] is +=1 thread safe

查看:67
本文介绍了是+ = 1线程安全的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述




我有一个软件以非常大的方式使用线程 - 比如

每秒产生数百个。


还有一段代码可以保持未完成的

线程的数量,只需


计数器+ = 1执行在开始线程之前和反击= = 1

完成之后。


一切都很简单,在程序生命结束时我期待

计数器为零。


但是我得到的值是-1,-2,1,2,3,并且通常是0,如预期的那样。


我用Lock来保护那些声明。{获取,释放}现在它总是

返回0.

但我还是不敢相信+ = 1不是线程安全操作。

任何线索?


-


Andy

Hi,

I have a piece of software which uses threads in very massive way - like
hundreds of them generated every second.

there is also a piece of code which maintains the number of outstanding
threads, simply

counter+=1 is executed when before starting the thread and counter-=1
after it finishes.

all is very simple and by the end of the program life I expect the
counter to zero out.

however I am getting values -1, -2, 1 ,2 ,3 and quite often 0 as expected.

I guarded those statement with Lock.{acquire,release} and now it always
returns 0.
But I still can not believe that +=1 is not a thread safe operation.
Any clue?

--

Andy

推荐答案

如果没有其他线程将访问计数器,则不存在

问题。 />
If no other threads will be accessing the counter, there will be no
problem.


AlFire< sp ****************** @ ggmail.comwrote:
AlFire <sp******************@ggmail.comwrote:

但我仍然不能相信+ = 1不是线程安全操作。


任何线索?
But I still can not believe that +=1 is not a thread safe operation.
Any clue?



声明:


x + = 1


相当于:


x = x .__ iadd __(1)


即函数调用后跟一个赋值。


如果对象是可变的那么这个*可能是*安全的,只要你永远不会做任何其他的x分配(__ iadd__方法将返回对象

变异,所以赋值在这种限制情况下是noop)。


整数是不可变的,因此赋值必须始终将x重新绑定到新的
对象。没有办法给出Python的语义,这可能是线程

安全。


生成数百个线程,BTW,一个非常好的方法在任何系统上都可以获得差劲的性能。不要那样做。创建几个线程并将这些线程的

操作放入队列中。如果你想要线程执行

并行调查使用子进程。


线程模块已经有一个函数来返回Thread的数量

当前活着的对象。

The statement:

x+=1

is equivalent to:

x = x.__iadd__(1)

i.e. a function call followed by an assignment.

If the object is mutable then this *may* be safe so long as you never do
any other assignment to x (the __iadd__ method will return the object being
mutated so the assignment would in this restricted case be a noop).

Integers are immutable, so the assignment must always rebind x to a new
object. There is no way given Python''s semantics that this could be thread
safe.

Generating hundreds of threads is, BTW, a very good way to get poor
performance on any system. Don''t do that. Create a few threads and put the
actions for those threads into a Queue. If you want the threads to execute
in parallel investigate using sub-processes.

The threading module already has a function to return the number of Thread
objects currently alive.


AlFire schrieb:
AlFire schrieb:




我有一个软件以非常大的方式使用线程 - 比如

每秒产生数百个。


还有一段代码可以维护未完成的b / b $ b $线程数,只需要在启动线程和counter- =
计数器+ = 1时执行1

完成后。


一切都非常简单,在程序生命结束时我期待

计数器归零。


但是我得到的值是-1,-2,1,2,3,并且通常是0,如预期的那样。


我用Lock来保护那些声明。{获取,释放}现在它总是

返回0.


但我仍然无法相信+ = 1不是线程安全操作。
Hi,

I have a piece of software which uses threads in very massive way - like
hundreds of them generated every second.

there is also a piece of code which maintains the number of outstanding
threads, simply

counter+=1 is executed when before starting the thread and counter-=1
after it finishes.

all is very simple and by the end of the program life I expect the
counter to zero out.

however I am getting values -1, -2, 1 ,2 ,3 and quite often 0 as expected.

I guarded those statement with Lock.{acquire,release} and now it always
returns 0.
But I still can not believe that +=1 is not a thread safe operation.



不要将增强的赋值与增量分配混淆,因为它提供了

by C(如果你的数据类型实际上适合单个可寻址的内存

现货,即)


python'的+ =这样的工作

a + = b< = a = a .__ iadd __(b)


因此,您实际上得到的情况是右边的表达式是

已经评估但尚未分配 - 然后另一个线程可以接管

控制,用旧值计算。


Diez

don''t confuse augmented assignment with incrementation as it is offered
by C (if your data-type actually fits into a single addressable memory
spot, that is)

python''s += works like this
a += b <=a = a.__iadd__(b)

Thus you actually get a situation where the expression on the right is
evaluated but not yet assigned - and then another thread can take over
control, computing with the old value of a.

Diez


这篇关于是+ = 1线程安全的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆