【问题标题】:Pthreads and mutexes; locking part of an arrayPthreads和互斥锁;锁定数组的一部分
【发布时间】:2011-02-16 16:00:06
【问题描述】:

我正在尝试使用 pthread 并行化操作。该过程类似于:

double* doSomething( .... )  {   
 double* foo;   
 foo = new double[220];  

 for(i = 0; i<20; i++)  
 {  
  //do something with the elements in foo located between 10*i and 10*(i+2)  
 }  

 return foo; 
}

for 循环中发生的事情可以按任何顺序完成,所以我想使用线程来组织它。

例如,我可以使用多个线程,这样每个线程都通过部分 for 循环,但在数组的不同部分工作。为了避免在处理重叠部分时出现问题,我需要锁定一些内存。

我怎样才能创建一个只锁定部分数组的互斥体(或其他东西)?

【问题讨论】:

  • 您真的是要让数据部分重叠吗? [0,20), [10,30), [20,40), ..., [190,210)?或者你的意思是不重叠: for(i=0; i

标签: c++ arrays pthreads mutex


【解决方案1】:

如果您使用的是最新的 gcc,您可以尝试标准算法的并行版本。见the libstdc++ parallel mode

【讨论】:

    【解决方案2】:

    如果你只是想确保数组的一部分被工作一次......

    创建一个全局变量:

    int _iNextSection;  
    

    每当一个线程准备好对一个节进行操作时,该线程都会以这种方式获取下一个可用节:

    iMySection = __sync_fetch_and_add(&_iNextSection, 1);
    

    __sync_fetch_and_add() 返回 _iNextSection 的当前值,然后递增 _iNextSection。 __sync_fetch_and_add() 是原子的,这意味着 __sync_fetch_and_add() 保证在另一个线程可以完成之前完成。无锁定,无阻塞,简单,快速。

    【讨论】:

      【解决方案3】:

      如果循环看起来和你写的一模一样,我会使用一个包含 21 个互斥体的数组,并在循环开始的第 (i + 1) 个互斥体上阻塞每个线程。

      比如:

      ...
      for (i = 0; i < 20; i++) {
       mutex[i].lock();
       mutex[i+1].lock();
       ...
       mutex[i+1].unlock();
       mutex[i].unlock();
      }
      

      逻辑是只有两个相邻的循环执行可以访问相同的数据(如果限制是[i * 10,(i + 2)* 10)),所以你只需要担心它们。

      【讨论】:

        猜你喜欢
        • 2020-12-07
        • 2018-05-23
        • 1970-01-01
        • 1970-01-01
        • 2010-12-17
        • 1970-01-01
        • 1970-01-01
        • 2015-10-26
        • 1970-01-01
        相关资源
        最近更新 更多