C 字节数组中的原子集位

C 字节数组中的原子集位,c,multithreading,locking,atomic,compare-and-swap,C,Multithreading,Locking,Atomic,Compare And Swap,如何原子地设置字节的位?我试图解决的问题是更新庞大的字节数组,比如uchar数据[262144]。我使用SET(index,value)一次只设置一个字节的2位,这意味着四个线程可以同时在一个字节中设置值。线程选择相同的字节进行更新是非常罕见的,但确实发生了这种情况。使这些操作线程安全的最有效方法是什么?请注意,我不能对每个数据项使用锁,因为锁太大、太慢 更糟糕的是,有时另一个字节数组data1[131072]也需要以线程安全的方式与以前的数据同时更新。但我计划合并这两个数组以简化问题,因此用原

如何原子地设置字节的位?我试图解决的问题是更新庞大的字节数组,比如uchar数据[262144]。我使用SET(index,value)一次只设置一个字节的2位,这意味着四个线程可以同时在一个字节中设置值。线程选择相同的字节进行更新是非常罕见的,但确实发生了这种情况。使这些操作线程安全的最有效方法是什么?请注意,我不能对每个数据项使用锁,因为锁太大、太慢


更糟糕的是,有时另一个字节数组data1[131072]也需要以线程安全的方式与以前的数据同时更新。但我计划合并这两个数组以简化问题,因此用原子方法更新第一个数组就足够了。

您必须使用CompareExchange原语。具体需要编写什么,取决于编译器和平台。然而,在理论上,它看起来如下

假设CompareExchange返回oldvalue,并且仅当oldvalue未更改时才自动更改值

do { oldvalue = bitset; newvalue = oldvalue|bitvalue; } while ( oldvalue != CompareExchange(&bitset,newvalue,oldvalue) ); 做{ oldvalue=位集; newvalue=oldvalue | bitvalue; }while(oldvalue!=CompareExchange(&bitset,newvalue,oldvalue));
因为CompareExchange是原子的,所以它将以原子方式设置位。但是您只能在最多一个处理器字大小的位集中原子地设置位。

是否可以,比如说,为每个线程维护一个单独的数据副本,然后在最后合并?不幸的是,不可以。大多数时候线程访问其分区中的数据,但它们也访问和更新其他分区。如果“其他分区”更新只是偶尔的,那么请求所有者线程进行更新怎么样?那可能会有很低的摊销成本。是的,我考虑过利用那个地方,这是我最后的选择。或者你可以每个分区使用一个锁,不是吗?通常,您可以通过散列对象索引并使用散列选择锁来减少对象数组中的锁争用;这允许您甚至动态地调整锁的数量。