我有一个全局的struct对象数组,可以由多个线程同时访问。但是,可以保证一次由两个不同线程访问的struct对象(在特定数组索引处)的各个数据成员将始终不同。
我的问题是我是否需要在此全局数组上使用互斥锁进行访问。
我的结构看起来像这样:
struct data{
string a;
int b;
uint16_t c;
};
修改
我有一个多线程UDP服务器程序,它创建固定数量的线程,并在同一个全局UDP套接字上执行recvfrom()阻塞。无论哪个线程首先接收数据报,都将处理该数据报。在这种情况下,为了便于存储客户端数据,我有了这个全局对象数组。就我而言,数据成员的处理将按以下顺序进行:string a, int b, uint16_t c
。没有两个线程可以访问同一个对象的同一个数据成员,因为客户端不会发送item b
的请求,直到它收到item a
的响应,并且该数组被client_number索引。
答案 0 :(得分:1)
基本上如果有100%的保证,两个不同的线程同时没有触及内存中的同一位置,则不需要使用互斥锁。
但是,如果您只有99.99%确定不会同时触摸它,那么您肯定需要互斥锁。
另一方面,使用互斥锁会以任何方式影响您的应用程序吗?因为,如果不是,可能值得为安全添加互斥锁,以防某些内容没有按预期运行。
答案 1 :(得分:1)
但是,可以保证一次由两个不同线程访问的struct对象的各个数据成员将始终不同。
如果不以某种方式同步你的线程,你如何保证?
如果您的意思是主题'a' 总是只访问成员'a',而主题'b' 始终仅访问成员'b',那么您将不需要锁定或其他同步。
否则,将需要一些同步。结构对象的 mutex 是一种方法。您提到的保证可以通过为各个结构成员提供互斥,或者为访问其中一个的代码部分提供关键部分。
所以,如果你真的可以提供这个保证,不,你不需要另一个互斥。但这意味着你已经已经进行了一些同步。
答案 2 :(得分:0)
如果线程1有可能需要读取线程2所做的更新,则必须使用某种同步 - 原子访问或互斥。没有这些,更新可能不可见。
答案 3 :(得分:-1)
在结构中进行一些填充,以确保访问两个相邻实例不会重叠。考虑:
struct data th[2];
想象一下内存中的符号布局:0000011111
。如果第一个线程开始写入[0]并且第二个读取th [1],则某些可能会重叠,具体取决于对齐方式。考虑对齐8个符号:WWWWWWWW111
。然后,在结束写入和恢复WWWWW11111
之前,第二个结构的前两个符号在读取时将不一致。