识别C

时间:2016-11-03 09:45:11

标签: c multithreading pthreads

所以我正在学习如何在C上使用线程,我写下了这段代码。

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>

#define number 3

void *funct(void *tid){
    printf("Thread %d\n", *((int*)tid));
    sleep(10);
    printf("Thread %d finishes\n", *((int*)tid));
    pthread_exit(NULL);
}

int main() {
    pthread_t threads[number];
    int i, status;
    printf("Pid: %d\n", getpid());
    for (i = 0; i < number; i++) {
        printf("Thread number %d\n", i);
        status = pthread_create(&threads[i], NULL, funct, (void*)&i);

        if(status != 0){
            printf("Error en la creación del hilo. La función devuelve %d\n", status);
            exit(-1);
        }
    }

    for (i = 0; i < number; i++) {
        pthread_join(threads[i], NULL);
    }
    return 0;
}

我的问题是我想在funct上用他们的号码识别它们,但有时输出是错误的。

Pid: 10142
Thread number 0
Thread number 1
Thread number 2
Thread 2
Thread 1
Thread 0
Thread 0 finishes
Thread 0 finishes
Thread 0 finishes

它不应该打印Thread 0 finishes 3次。我认为tid的内容在线程调用之间发生了变化,这就是为什么它会打印另一个值。我该如何解决这个问题?

2 个答案:

答案 0 :(得分:3)

您有一个data race,因为您将同一个变量i的地址传递给所有线程函数。 您可以使用临时数组来传递线程&#34;数字&#34;。

   int thr_id[number];
   for (i = 0; i < number; i++) {
        thr_id[i] = i;
        printf("Thread number %d\n", i);
        status = pthread_create(&threads[i], NULL, funct, &thr_id[i]);
        ...

另外,请注意C中无需使用无效指针。

答案 1 :(得分:1)

由于您将单个变量的变量传递给不同的线程,因此您有数据竞争,因此该变量的值将随着创建更多线程而更改。

在大多数/典型的实现中,您可以将整数转换为指针值本身,并且不再使用整数数组:

status = pthread_create(&threads[i], NULL, funct, (void *) (intptr_t) i);

然后在函数内部将接收的指针强制转换为整数:

printf("Thread %d\n", (int) (intptr_t) tid);

intptr_t的尺寸大于void *的尺寸时,来自int的演员应该有助于避免警告。例如,请参阅this question