使用全局变量来控制单独线程中的while循环

时间:2012-04-10 14:56:05

标签: c pthreads

gcc(GCC)4.6.3     C89     的valgrind-3.6.1

您好,

更新了代码段 +++++++++++++++++++++++++++++++++++

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);
}

非常感谢任何建议,

3 个答案:

答案 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);