Boost 版本 - 1.47 我找不到 boost::interprocess::interprocess_sharable_mutex,但看起来它是向前声明的。这真的支持吗?
我可以看到 boost::interprocess::interprocess_upgradable_mutex 是向前声明的,并且也被定义了。但是,我无法找到可以使用此互斥体的相应条件变量。有任何想法吗 ?
我有一部分代码,其中一个线程调用如下内容:
cond->notify_all();
delete cond;
Run Code Online (Sandbox Code Playgroud)
和
std::condition_variable_any cond;
Run Code Online (Sandbox Code Playgroud)
Afaik,这应该可行,因为我应该被允许删除条件变量,一旦我通知所有等待它的线程,它们就不必从等待调用中恢复。
在 Windows 上,有时会因错误而崩溃:
mutex destroyed while busy
Run Code Online (Sandbox Code Playgroud)
打印到标准输出
在linux上,使用clang 3.5,这工作得很好,在Windows上,我使用Visual Studio 2013,使用v120 takeit,v120是默认的。
是我做错了什么,是我误解了标准,还是 M$ 在这里做错了什么?如果是这样,我该如何解决这个问题?
我正在使用一个实现了两个 posix 函数的系统
mq_timedreceive() and pthread_cond_timedwait()
Run Code Online (Sandbox Code Playgroud)
这两个函数都使用基于 CLOCK_REALTIME 的绝对超时。该时钟在系统启动过程中的不同时间会发生变化,并且可以向后或向前移动 10 秒到几小时。
开放组说道:
如果支持Timers选项,则超时应基于CLOCK_REALTIME时钟;如果不支持 Timers 选项,则超时应基于 time() 函数返回的系统时钟。(mq_timedreceive)
对于操作员不连续地提前系统时钟的情况,预计实现会处理在中间时间到期的任何定时等待,就好像该时间实际上已经发生一样。(pthread_cond_timedwait())。
然而,这对于时钟向后设置的情况并没有提供任何指导。
QNX 通过提供解决了这个问题
mq_timedreceive_monotonic().
Run Code Online (Sandbox Code Playgroud)
mq_timedreceive_monotonic() 函数是 QNX Neutrino 扩展;它与 mq_timedreceive() 类似,但它使用 CLOCK_MONOTONIC,因此超时不受系统时间更改的影响。
有没有好的方法在linux中实现QNX功能?
对于 mq_timedreceive(),我可以使用 mq_receive() 和 poll()。但对于条件变量我还没有想出一个干净的方法。我可以使用计时器和信号,但这似乎太复杂了。
当然,另一个解决方案是不调整时钟或使用从 CLOCK_MONOTONIC 派生的不同时钟,但我没有自由更改设计。
我在网上找不到任何pthread_cond_wait在Mac OS X上出现奇怪的证据,但似乎对我来说似乎没有最简单的测试.
功能
int pthread_cond_wait(pthread_cond_t *, pthread_mutex_t * );
Run Code Online (Sandbox Code Playgroud)
应该解锁互斥参数#2,然后等待条件参数#1发送信号.我写了一个简单的程序来测试它,并测试虚假的唤醒:
#include <stdio.h>
#include <pthread.h>
pthread_t spin_thread;
pthread_mutex_t spin_mutex;
pthread_cond_t spin_cond;
int actual = 0;
void *condspin( void *v ) {
int expected = 0;
for ( ;; ) {
if ( actual != expected ) printf( "unexpected %d\n", actual );
else printf( "expected %d\n", actual );
pthread_mutex_lock( &spin_mutex );
printf( "locked\n" );
expected = actual + 1;
pthread_cond_wait( &spin_cond, &spin_mutex );
}
return NULL;
}
int main( …Run Code Online (Sandbox Code Playgroud) 我最近一直在和pthreads合作,而且还有一件小事我还是不太了解.我知道条件变量旨在等待特定条件成立(或"发信号").我的问题是,这与普通的互斥体有何不同?
根据我的理解,当条件变为真时,条件变量不仅仅是具有额外逻辑的互斥锁来解锁另一个互斥锁(并再次锁定它)?
Psuedocode示例:
mutex mymutex;
condvar mycond;
int somevalue = 0;
onethread()
{
lock(mymutex);
while(somevalue == 0)
cond_wait(mycond, mymutex);
if(somevalue == 0xdeadbeef)
some_func()
unlock(mymutex);
}
otherthread()
{
lock(mymutex);
somevalue = 0xdeadbeef;
cond_signal(mycond);
unlock(mymutex);
}
Run Code Online (Sandbox Code Playgroud)
因此,此示例中的cond_wait解锁mymutex,然后等待mycond发出信号.
如果是这样,那么条件变量不仅仅是具有额外魔力的互斥量吗?或者我对互斥和条件变量的基本基础有误解?
我有thread1正在等待来自thread2的条件.但它可能是thread2永远不会发出条件变量的信号.所以我wait在线程1 的调用中添加了一个超时,如下所示:
cv.acquire()
cv.wait(1.0)
cv.release()
Run Code Online (Sandbox Code Playgroud)
如何知道条件变量是否已发出信号或是否发生超时?wait似乎没有返回任何价值.条件对象的python文档没有提供关于此的线索.
是否可以使用单个条件变量进行双向同步(即在同一条件变量的不同时间等待两个不同的条件)?我确信在任何时候只有一个线程会在条件变量上等待.下面的示例代码说明了我在想什么:
#include <condition_variable>
#include <thread>
#include <mutex>
#include <iostream>
std::condition_variable condvar;
std::mutex mutex;
int i;
void even()
{
while (i < 10000) {
std::unique_lock<std::mutex> lock(mutex);
if (i % 2 != 0) {
condvar.notify_one();
condvar.wait(lock, [&](){ return i % 2 == 0; });
}
i++;
std::cout << i << std::endl;
}
condvar.notify_one();
}
void odd()
{
while (i < 10001) {
std::unique_lock<std::mutex> lock(mutex);
if (i % 2 != 1) {
condvar.notify_one();
condvar.wait(lock, [&](){ return i % 2 == 1; });
} …Run Code Online (Sandbox Code Playgroud) 我是多线程的新手.在使用条件变量在C++ 11中编写多线程代码时,我使用以下构造
while(predicate) {
cond_var.wait(&lock);
}
Run Code Online (Sandbox Code Playgroud)
但是,我一直在阅读Deitel关于操作系统的第三版书(第6页),其中使用了以下结构
if(predicate) {
cond_var.wait(&lock);
}
Run Code Online (Sandbox Code Playgroud)
那么,有什么区别?为什么这本书不能用呢?是不是虚假的称呼问题?
我正在通过REMZI的并发部分,而在通过互斥体部分时,对此感到困惑:
为了避免繁忙的等待,互斥体实现采用park()/ unpark()机制(在Sun OS上),该机制将等待线程与其线程ID放入队列中。稍后,pthread_mutex_unlock()它将从队列中删除一个线程,以便调度程序可以选择该线程。同样,Futex的实现(Linux上的互斥量实现)使用相同的机制。
我仍然不清楚队列在哪里。它是在运行进程的地址空间中还是在内核内部?
我对条件变量的另一个疑问。是pthread_cond_wait()并pthread_cond_signal()使用普通信号和等待方法,还是使用它们的某些变体?
在我们的Android应用程序中,我们有UI组件和核心C++ 11模块.线程正在运行std::chrono::system_clock::time_point,如下所示:
while(this->m_ConditionVariable.wait_until(lock, this->m_Object.to_time_point())
== std::cv_status::no_timeout)
{
// ... handle any notify() or arbitrary sleep breaks
}
Execute(); // <--- not being called consistently
Run Code Online (Sandbox Code Playgroud)
现在,我们正在测试1分钟time_point.如果该应用程序正在使用中,则会Execute()按预期调用该应用程序.但是,如果将应用程序移动到后台或者即使屏幕被锁定,那么Execute()-s行为也不一致.
有时,它可以每分钟正常工作15分钟,然后在2分钟或3分钟或10分钟后调用,而不是固定1分钟.使用调试,我们检查了,time_point提供的是正确的.
假设我们在调试模式下运行应用程序(使用Android Studio),那么即使在后台和屏幕锁定模式下也能正常运行.
Android在后台运行的应用程序是否具有任何线程优先级?
更新1:基本上后台线程正在收集位置信息.我在下面提到了问题,这表明在Android中,当手机被锁定时,线程执行就会停止.我坚持这个问题了吗?
当屏幕进入睡眠状态时,应用似乎停止工作
更新2:部分唤醒锁定,它工作正常.但不确定这是否是一个很好的解决方案.如果这是唯一的方法,那么我会很感激如何最佳地使用它的策略.
更新3:如果我wait()用较小的替换sleep(),那么即使没有任何Android唤醒锁也可以正常工作.但是我们还没有对它进行回归测试.
c++ ×5
pthreads ×4
c++11 ×2
mutex ×2
posix ×2
android ×1
android-ndk ×1
boost ×1
c ×1
concurrency ×1
interprocess ×1
python ×1
thread-sleep ×1