一位同事最近遇到了一个问题,归结为我们认为具有两个线程的C++应用程序中的以下事件序列:
线程A持有互斥锁.
当线程A持有互斥锁时,线程B会尝试锁定它.由于它被保持,线程B被暂停.
线程A完成它持有互斥锁的工作,从而释放互斥锁.
此后不久,线程A需要触摸受互斥锁保护的资源,因此它会再次锁定它.
似乎线程A再次被赋予互斥锁; 线程B仍在等待,即使它首先"询问"锁定.
这个事件序列是否适合C++ 11 std::mutex和/或pthreads 的语义?老实说我以前从未想过互斥体的这个方面.
我有两个线程,一个在紧密循环中工作,另一个偶尔需要与第一个执行同步:
// thread 1
while(1)
{
lock(work);
// perform work
unlock(work);
}
// thread 2
while(1)
{
// unrelated work that takes a while
lock(work);
// synchronizing step
unlock(work);
}
Run Code Online (Sandbox Code Playgroud)
我的意图是,通过获取锁,线程2可以有效地暂停线程1并执行必要的同步.线程1还可以通过解锁来提供暂停,如果线程2没有等待锁定,则重新锁定并返回工作.
我遇到的问题是互斥是不公平的,所以线程1快速重新锁定互斥锁并使线程2饿死.我试图使用pthread_yield,到目前为止似乎运行正常,但我不确定它是否会起作用所有系统/核心数量.有没有办法保证线程1总能屈服于线程2,即使在多核系统上也是如此?
处理此同步过程的最有效方法是什么?
假设我在调用时阻塞了多个线程pthread_mutex_lock().当互斥锁变得可用时,调用的第一个线程是否pthread_mutex_lock()获得锁定?也就是说,pthread_mutex_lock()按FIFO顺序调用?如果不是,那么它们的订单是什么?谢谢!
如果我设置3个线程来等待释放互斥锁,它们是否根据它们请求的顺序形成队列,或者它是未定义的行为(即我们不知道哪个将首先获取它)?
我有这个有趣的情况.
我有一堆结构字符串.
struct foo
{
string mStringName;
}
vector<foo> mFoos;
Run Code Online (Sandbox Code Playgroud)
我也有一个字符串引用队列
queue<string&> mStringQueue;
Run Code Online (Sandbox Code Playgroud)
最后,我有一个接受const字符串的函数&
void Bar(const string&);
Run Code Online (Sandbox Code Playgroud)
继承人的情况.
//...in some loop
currentFoo = mFoos[index];
// Queue up the string name.
mStringQueue.push(currentFoo.mStringName);
//...Later on, go through our queue and pass each one to the function.
for (int queueIndex = 0; queueIndex < mStringQueue.size(); queueIndex++)
{
Bar(mStringQueue.front());
mStringQueue.pop();
}
Run Code Online (Sandbox Code Playgroud)
这给了我以下编译错误:
错误C2664: '的std ::队列<_Ty> ::推':无法从 '字符串' 到 '串(&)' 转换参数1
我是definitley无法绕过字符串引用和诸如此类的东西,所以任何帮助都将非常感激
正如问题所述,是std::mutex公平的吗?即,如果线程A锁定了互斥锁,然后B和C按此顺序调用'lock()',它们是否会以相同的顺序获取互斥锁上的锁定,或者是否未指定顺序?
该文件完全不解决这个问题.
比方说,如果我有三个线程都通过互斥锁访问相同的互斥部分.
让我举个例子.
第一个线程探测互斥锁并首先获得其所有权:
//THREAD 1
//TIME: 2013-03-13 01:00:00.000Z
WaitForSingleObject(hMutex, INFINITE);
//Performs the operation that lasts 50 ms
ReleaseMutex(hMutex);
Run Code Online (Sandbox Code Playgroud)
然后10毫秒后,线程2也请求它:
//THREAD 2
//TIME: 2013-03-13 01:00:00.010Z
WaitForSingleObject(hMutex, INFINITE);
//Do work
ReleaseMutex(hMutex);
Run Code Online (Sandbox Code Playgroud)
20毫秒后,线程3也请求它:
//THREAD 3
//TIME: 2013-03-13 01:00:00.030Z
WaitForSingleObject(hMutex, INFINITE);
//Do work
ReleaseMutex(hMutex);
Run Code Online (Sandbox Code Playgroud)
在这种情况下,我可以确定线程2将始终在线程3之前获得互斥锁所有权(因为它可以说是"排在第一位"),或者它是否完全随意获得线程2和3之间的所有权?
如果它与互斥锁是任意的,如何确保第一个等待的线程首先获得所有权?