0

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. 我也宣布它为易变的。+++++++++++++++++++++++++++++++++++++++++

我在每 1/2 秒轮询一次的工作线程中运行一个 while 循环。在用户输入 ctrl-c 后,我使用全局变量 start_receiving 来控制它,它会将值更改为 false。

拥有这样的全球是一种好习惯吗?

我在运行 hlgrind 时遇到这两个错误时询问的原因:

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

非常感谢您的任何建议,

4

3 回答 3

3

不,这是非常糟糕的做法。

至少,变量应该volatile避免被优化掉。

不过,您确实应该考虑为此使用一些真正的多线程原语,例如互斥锁(以保护共享状态,以便两个线程不会同时访问它)和原子变量(以确保状态是防螺纹的)。

于 2012-04-10T14:58:40.823 回答
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);
于 2012-04-11T06:42:38.713 回答
1

Polling isn't a right way. I suggest you to read about conditional variables

于 2012-04-10T15:20:46.850 回答