我在动态库中有一个逻辑,它运行主可执行文件请求的一些服务。
从库代码调用start_service
后,在准备好服务之前需要做一些准备工作,在此期间,主代码不应尝试访问服务。
要在服务准备就绪时通知主代码,我使用条件变量并发出主可执行文件的信号。
在主代码等待条件变量之前,我想听听一些关于在库变得可用时处理情况的最佳方法的建议。在这种情况下,等待可以永远持续......
这是服务代码:
extern pthread_cond_t cnd;
extern pthread_mutex_t mtx;
void start_service()
{
// getting serviceable.
pthread_cond_signal(&cnd);
main_loop();
}
这是主要代码。
pthread_cond_t cnd;
pthread_mutex_t mtx;
int main()
{
pthread_cond_init(&cnd,NULL);
pthread_mutex_init(&mtx, NULL);
std::thread mytrd(&start_service);
...
pthread_mutex_lock(&mtx);
pthread_cond_wait(&cnd, &mtx); // what happens if we get here after the signal already sent.
pthread_mutex_unlock(&mtx);
...
}
P.S期望的行为应该是主代码避免等待条件变量已经发出信号。
答案 0 :(得分:2)
您需要一个谓词并将wait
括在谓词检查中:
pthread_mutex_lock(&mtx);
while( ! predicate ) pthread_cond_wait(&cnd, &mtx);
pthread_mutex_unlock(&mtx);
通过这种方式,线程不会在不需要时开始等待事件。
你需要这个的第二个原因是为了避免可能发生的虚假唤醒,即使另一个线程没有发出信号,pthread_cond_wait
可能会返回。
然后另一个线程必须执行(您需要锁定互斥锁以保护谓词):
pthread_lock_mutex(&mtx);
predicate = true;
pthread_cond_signal(&cnd);
pthread_unlock_mutex(&mtx);
答案 1 :(得分:2)
您可以使用初始计数为0
的信号量,因此main
会被阻止,直到start_service()
将信号量计数增加到1
。如果在阻止调用main
之前{1}},start_service()
将信号量计数增加到1
,main将永远不会进入等待状态。如下所示。
void start_service()
{
// getting serviceable.
sem_post(&sem_mutex);//increases to 1
main_loop();
}
int main()
{
sem_init(&sem_mutex, 0, 0);//initially blocked.
std::thread mytrd(&start_service);
sem_wait(&sem_mutex);
...
}