【问题标题】:Array of struct objects - Thread safety结构对象数组 - 线程安全
【发布时间】:2015-10-03 02:53:36
【问题描述】:

我有一个由多个线程同时访问的全局结构对象数组。但是,可以保证由两个不同线程一次访问的结构对象(在特定数组索引处)的各个数据成员总是不同的。

我的问题是我是否需要在这个全局数组上设置互斥锁才能访问它。

我的结构如下所示:

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 索引。

【问题讨论】:

  • 你怎么知道两个不同的线程不会同时使用同一个对象?
  • @Mr. E - 索引可能按偶数/奇数、下三分之一、中三分之一、上三分之一等分布在线程上。
  • 在这种情况下,两个不同的线程永远不会使用同一个对象,但是 OP 说两个线程不会同时使用同一个对象。

标签: c multithreading


【解决方案1】:

基本上,如果 100% 保证两个不同的线程不会同时接触内存中的同一位置,则不需要使用互斥锁。

但是,如果您只有 99.99% 的把握不会同时触及它,那么您肯定需要互斥锁。

另一方面,使用互斥锁会以任何方式影响您的应用程序吗?因为,如果不是这样,为了安全起见,可能值得添加一个互斥锁,以防某些东西没有按照您的预期运行。

【讨论】:

    【解决方案2】:

    但是可以保证,两个不同线程一次访问的结构对象的各个数据成员总是不同的。

    如果不以某种方式同步你的线程,你如何保证这一点?

    如果您的意思是 thread 'a' always 只访问 member 'a'thread 'b' 总是只访问成员'b',那么你就不需要锁或其他同步。

    否则,您需要一些同步。结构对象的 mutex 是一种方法。您提到的保证可以通过为单个结构成员设置 mutexes 或为访问其中之一的代码部分设置 关键部分 来提供。

    所以,如果你真的可以提供这个保证,不,你不需要另一个 mutex。但这意味着您已经拥有一些同步。

    【讨论】:

      【解决方案3】:

      如果线程 1 有可能需要读取线程 2 所做的更新,您将不得不使用某种同步 - 原子访问或互斥锁。没有这些,更新可能不可见。

      【讨论】:

        【解决方案4】:

        在结构中进行一些填充以确保访问两个相邻实例不会重叠。考虑:

        struct data th[2];
        

        想象一下内存中的符号布局:0000011111。如果第一个线程开始写入 th[0] 并且第二个读取 th[1] ,则某些可能会重叠,具体取决于对齐方式。考虑对齐 8 个符号:WWWWWWWW111。那么在结束写入和恢复WWWWW11111之前,第二个结构的前两个符号在读取时会不一致。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-01-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-12-10
          相关资源
          最近更新 更多