您好,
更新了代码段 +++++++++++++++++++++++++++++++++++
void *thread_recv_fd()
{
pthread_mutex_lock(&mutex_queue);
while(start_receiving) {
pthread_mutex_unlock(&mutex_queue);
pthread_mutex_lock(&mutex_queue);
queue_remove();
pthread_mutex_unlock(&mutex_queue);
usleep(500);
}
pthread_exit(NULL);
}
使用上面的锁现在看起来非常难看。我在阅读start_receiving
时仍然遇到种族错误。我也宣称它也是不稳定的。
+++++++++++++++++++++++++++++++++++++
我在一个工作线程中运行一个while循环,每1/2秒轮询一次。在用户输入ctrl-c之后,我使用全局变量start_receiving控制它,它会将值更改为false。
拥有这样的全球化是一种很好的做法吗?
当我运行helgrind时,我问到这两个错误的原因是:
==6814== Possible data race during write of size 4 at 0x601958 by thread #1
==6814== at 0x401131: main (driver.c:78)
==6814== This conflicts with a previous read of size 4 by thread #2
==6814== at 0x4012A7: thread_recv_fd (driver.c:127)
这是代码行:
driver.c:78 is this line of code start_receiving = FALSE;
driver.c:127 is this line of code while(start_receiving) in the while loop
源代码,只是重要的片段:
static int start_receiving = FALSE;
int main(void)
{
pthread_t thread_recv_id;
pthread_attr_t thread_attr;
/* Start polling as soon as thread has been created */
start_receiving = TRUE;
do {
/* Start thread that will send a message */
if(pthread_create(&thread_recv_id, &thread_attr, thread_recv_fd, NULL) == -1) {
fprintf(stderr, "Failed to create thread, reason [ %s ]",
strerror(errno));
break;
}
}
while(0);
/* Wait for ctrl-c */
pause();
/* Stop polling - exit while loop */
start_receiving = FALSE;
/* Clean up threading properties */
pthread_join(thread_recv_id, NULL);
pthread_exit(NULL);
}
void *thread_recv_fd()
{
while(start_receiving) {
pthread_mutex_lock(&mutex_queue);
queue_remove();
pthread_mutex_unlock(&mutex_queue);
usleep(500);
}
pthread_exit(NULL);
}
非常感谢任何建议,
答案 0 :(得分:3)
不,这是非常糟糕的做法。
至少,变量应为volatile
,以避免被优化。
你应该真正考虑使用一些真正的多线程原语,例如互斥(为了保护共享状态,以便两个线程不同时访问它)和原子变量(要制作)确保状态是防线的。)
答案 1 :(得分:1)
投票不是正确的方法。 我建议你阅读conditional variables
答案 2 :(得分:1)
你可以使用原子,但这里最简单的解决方案就是在控制变量周围使用锁定。例如:
static int start_receiving = FALSE;
static pthread_mutex_t start_receiving_lock = PTHREAD_MUTEX_INITIALIZER;
int is_receiving(void)
{
int r;
pthread_mutex_lock(&start_receiving_lock);
r = start_receiving;
pthread_mutex_unlock(&start_receiving_lock);
return r;
}
然后在线程函数中:
void *thread_recv_fd()
{
while(is_receiving()) {
pthread_mutex_lock(&mutex_queue);
queue_remove();
pthread_mutex_unlock(&mutex_queue);
usleep(500);
}
pthread_exit(NULL);
}
..并在主要功能中:
pthread_mutex_lock(&start_receiving_lock);
start_receiving = 1;
pthread_mutex_unlock(&start_receiving_lock);