pthread执行的奇怪结果

时间:2015-10-24 03:10:02

标签: macos pthreads

我有这段代码来测试Mac OS X中的pthread。

#include <stdio.h>
#include <string.h>
#include <pthread.h>

//    A thread that just exits
void*  mythread(void *arg) { 
    int tArg;

    tArg = *(int*)arg;
    printf("Received %d\n", tArg);
    return 0; 
}

int main (int argc, char *argv[]) {
    int err, count = 0;

    pthread_t thread;

    while (1) {
        err = pthread_create(&thread, 0, mythread, &count);
        if (err != 0) {
            printf("Count: %d Error: %d '%s'\n", count, err, strerror(err));
        }
        count += 500;
        if (count == 5000) break;
    }

    return 0;
}

这是其中一项结果:

Received 3000
Received 3500
Received 3000
Received 3500
Received 3000
Received 3000
Received 3500
Received 4500
Received 4500
Received -2009390077

结果似乎对我来说很奇怪,因为它不是从0开始,而是多个重复和奇怪的最后一个值。可能有什么问题?

1 个答案:

答案 0 :(得分:4)

您在每次迭代时都会覆盖thread,这会产生意想不到的后果。

您将count的地址传递给线程(int *),它从3000开始并不奇怪;当第一个线程实际执行时,int *count必须已经增加到该值。

其他线程同时从主进程的堆栈中读取相同的值,因此您可以重复。

可以解释最后的结果,因为线程未正确连接。当最后一个线程读取count时,变量不再在堆栈上,因为main函数返回或正在返回。

正确的代码应该更像这样:

#include <stdio.h>
#include <string.h>
#include <pthread.h>

//    A thread that just exits
void*  mythread(void *arg) { 
    int tArg;

    tArg = *(int*)arg;
    printf("Received %d\n", tArg);
    return 0; 
}

int main (int argc, char *argv[]) {
    int err, num = 0, count[10];
    pthread_t thread[10];

    for (num = 0; num < 10; num++) {
        /* this is horrible, these could be statically initialized */
        if (!num) 
            count[num] = 500;
        else count[num] = count[num-1] + 500;

        /* each thread should have it's own pthread_t and int* */
        /* do not change the count[num] of another thread */
        err = pthread_create(&thread[num], 0, mythread, &count[num]);
        if (err != 0) {
            printf("Count: %d Error: %d '%s'\n", count[num], err, strerror(err));
        }
    }

    for (num = 0; num < 10; num++) {
        pthread_join(thread[num], NULL);
    }

    return 0;
}

请注意,仍然无法保证执行顺序,您可能会得到如下输出:

Received 1000
Received 2000
Received 2500
Received 1500
Received 500
Received 3000
Received 3500
Received 4000
Received 4500
Received 5000

这很正常。