void WorkHandler::addWork(Work* w){
printf("WorkHandler::insertWork Thread, insertWork locking \n");
lock();
printf("WorkHandler::insertWork Locked, and inserting into queue \n");
m_workQueue.push(w);
signal();
unLock();
}
Run Code Online (Sandbox Code Playgroud)
我按照教程,得到了这个.我想知道是否可以像这样更改singal()和unLock()的顺序
void WorkHandler::addWork(Work* w){
printf("WorkHandler::insertWork Thread, insertWork locking \n");
lock();
printf("WorkHandler::insertWork Locked, and inserting into queue \n");
m_workQueue.push(w);
unLock();
signal();
}
Run Code Online (Sandbox Code Playgroud)
如果我不能这样做,你能否详细说明为什么我不允许这样做?提前致谢.
bdo*_*lan 22
首先,这里没有正确性问题.任何订单都可以.回想一下,无论何时使用条件变量,都必须在等待时循环一个谓词:
pthread_mutex_lock(mutex);
while (!predicate)
pthread_cond_wait(cvar);
pthread_mutex_unlock(mutex);
Run Code Online (Sandbox Code Playgroud)
通过解锁后发出信号,您不会引入任何正确性问题; 线程仍然保证会被唤醒,最糟糕的情况是另一个唤醒首先出现 - 此时它会看到谓词变为真,然后继续.
但是,可能会出现两个可能的性能问题.
虚假醒来.如果您在解锁后发出信号,则另一个线程可能会发出另一个唤醒.请考虑以下情形:
如您所见,这可能会引入虚假唤醒,这可能会浪费一些CPU时间.
就个人而言,我认为无论如何都不值得担心.您不经常知道您的实现是否支持将服务器从条件变量移动到互斥等待队列,这是您可以用来决定使用哪个的唯一真正标准.
我的直觉是,如果我不得不选择,信号后解锁是轻微的效率低下,需要一个三线的比赛,而不是两线比赛中为"快点,等待不太可能推出的低效率, "条件.但是,这并不值得担心,除非基准测试显示过多的上下文切换开销.
| 归档时间: |
|
| 查看次数: |
7802 次 |
| 最近记录: |