phaser

栏目: 后端 · 发布时间: 5年前

内容简介:“phaser”是一个同步原语,它允许线程知道所有其他线程已经通过执行中的某个点,但没有阻塞任何这些线程。 在调用者想要在解除分配之前保证共享资源不再可见的情况下,它非常有用。任何数量的线程都可以进入和退出由移相器保护的“关键区域”; 他们使用例程退出phaser_enter和phaser_exit。 这些功能是非等待,非阻塞,完全可重入,绝对可靠和异步信号安全。另一个线程(一次最多一个)可以同时调用phaser_drain。 此函数会阻塞所有线程在调用phaser_drain之前进入受监控区域 相应的调用

“phaser”是一个同步原语,它允许线程知道所有其他线程已经通过执行中的某个点,但没有阻塞任何这些线程。 在调用者想要在解除分配之前保证共享资源不再可见的情况下,它非常有用。

任何数量的线程都可以进入和退出由移相器保护的“关键区域”; 他们使用例程退出phaser_enter和phaser_exit。 这些功能是非等待,非阻塞,完全可重入,绝对可靠和异步信号安全。

另一个线程(一次最多一个)可以同时调用phaser_drain。 此函数会阻塞所有线程在调用phaser_drain之前进入受监控区域 相应的调用phaser_exit退出该区域。

phaser_enter和phaser_exit是异步信号安全的并且完全可重入,使得它们非常适用于其他同步原语可能很麻烦的信号处理程序。

性能

Phaser非常重量级。 phaser_enter和phaser_exit是常见情况下的原子增量和原子减量。 在Intel i7-4600U上,phaser_enter和phaser_exit对在大约28个周期内完成。 如果phaser_drain同时运行,那么成本大约会翻倍。

虽然移相器本身可以充分执行,但它只占用一个缓存行,可能会在严重争用的情况下损害性能。 通过使用多个相位器(每个相位器位于不同的高速缓存线上),调用者可以在这种情况下将性能提高两倍。 进入关键部分的线程可以根据CPU亲和性选择移相器,并且想要在所有读取器上同步的线程可以依次调用每个高速缓存行上的phaser_drain。

可移植性

Phaser依赖于操作系统提供某种等待地址功能。 在 Linux 上,我们直接使用futex。 在Windows上,可以使用WaitOnAddress。 在FreeBSD上,umtx应该可以工作; 在iOS上,内核的psynch_cvwait psynch_cvsignal就足够了。

例子

请注意,worker_threads()不执行重量级同步,并且对worker_threads()和atomically_increment_array()的任何数量的调用都可以并发运行。

std::vector<int>* g_array;
pthread_mutex_t array_phaser_lock = PTHREAD_MUTEX_INITIALIZER;
phaser_t array_phaser;

void init()
{
  pthread_mutex_init(&array_phaser_lock);
  phaser_init(&array_phaser);
}

void worker_threads()
{
  phaser_phase phase;
  for(;;) {
    phase = phaser_enter(array_phaser);
    operate_on_array(array);
    phaser_exit(array_phaser, phase);
  }
}

void atomically_increment_array()
{
  std::vector<int>* old_array;
  std::vector<int>* new_array;
  bool success;

  do {
    phaser_enter(array_phaser);

    old_array = __atomic_load_n(&g_array, __ATOMIC_ACQUIRE);
    // NB: in real code, the std::vector constructor can throw,
    // and calling code should take care to exit the phaser
    // critical section if it does.
    new_array = new std::vector<int>(*old_array);
    for(auto it = new_array->begin(); it != new_array->end(); ++it) {
      *it += 1;
    }

    // Important to use __ATOMIC_RELEASE on the success path:
    // other threads must see only fully-constructed vector.
    success =
      __atomic_compare_exchange_n(
        &g_array,
        &old_array,
        new_array,
        true // weak: we loop anyway,
        __ATOMIC_RELEASE,
        __ATOMIC_RELAXED);

    phaser_exit(array_phaser);

    if(!success) {
       * Someone else beat us to the increment, so try again.
       delete new_array;
    }
  } while(!success);

   // We exclusively own the old array.  Wait for pending readers
   // to finish.

   pthread_mutex_lock(&array_phaser_lock);
   phaser_drain(array_phaser);
   pthread_mutex_unlock(&array_phaser_lock);

   // Now we know that nobody is using old_array: all
   // references to array occur inside a phaser critical
   // section, and the call to phaser_drain ensured that
   // all critical sections that began while g_array still
   // pointed at old_array have now terminated.

  delete old_array;
}
复制代码

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

腾讯之道

腾讯之道

艾永亮、刘官华、梁璐 / 机械工业出版社 / 2016-7-19 / 59

放眼整个中国乃至全球,腾讯都是一家成功的互联网企业,它代表中国企业在世界互联网版图中竖起了一面高高的旗帜。腾讯为何能取得如此大的成就,它的成功方法和商业逻辑是什么?你是不是和无数中国企业和商界人士一样,都想向腾讯取取经,但是又不得其门而入? 腾讯一直以低调、务实著称,所 以腾讯及其内部员工都极少对外界分享他们的经验;加之腾讯的商业模式多元、业务繁多且交叉、体量又极其庞大,使得从外部来系统研究......一起来看看 《腾讯之道》 这本书的介绍吧!

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具