Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/61.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/dart/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 为什么我创建的线程没有按顺序打印?_C_Multithreading_Pthreads_Race Condition - Fatal编程技术网

C 为什么我创建的线程没有按顺序打印?

C 为什么我创建的线程没有按顺序打印?,c,multithreading,pthreads,race-condition,C,Multithreading,Pthreads,Race Condition,我有这个计划: void *func(void *arg) { pthread_mutex_lock(&mutex); int *id = (int *)arg; printf("My ID is %d\n" , *id); pthread_mutex_unlock(&mutex); } int main() { int i; pthread_t tid[3]; // Let us create three threa

我有这个计划:

void *func(void *arg) {
    pthread_mutex_lock(&mutex);
    int *id = (int *)arg;

    printf("My ID is %d\n" , *id);
    pthread_mutex_unlock(&mutex);
}

int main() {
    int i;
    pthread_t tid[3];

    // Let us create three threads
    for (i = 0; i < 3; i++) {
        pthread_create(&tid[i], NULL, func, (void *)&i);
    }

    for (i = 0; i < 3; i++) {
        pthread_join(tid[i], NULL);
    }

    pthread_exit(NULL);
    return 0;
}
但我得到的是随机输出,例如:

My ID is 0
My ID is 0
My ID is 2
因为我已经添加了互斥锁,所以我认为它可以解决这个问题。我还做错了什么?这与比赛条件有关吗?

不,不涉及比赛条件。(my b)i上可能存在争用条件,因为所有线程都访问它。每个线程都以指向i的指针开始。然而,主要的问题是,不能保证线程将启动并运行关键部分,而我将按照您期望的顺序保存您期望的值

我假设您全局声明变量
mutex
,并在某个地方调用
pthread\u mutex\u init()
对其进行初始化

互斥锁非常好,一次只允许一个线程访问代码的关键部分。因此,您编写的代码创建了所有三个并行运行的线程,但每次只允许一个线程运行以下代码

int *id = (int *)arg;

printf("My ID is %d\n" , *id);
不,不涉及比赛条件。(my b)i上可能存在争用条件,因为所有线程都访问它。每个线程都以指向i的指针开始。然而,主要的问题是,不能保证线程将启动并运行关键部分,而我将按照您期望的顺序保存您期望的值

我假设您全局声明变量
mutex
,并在某个地方调用
pthread\u mutex\u init()
对其进行初始化

互斥锁非常好,一次只允许一个线程访问代码的关键部分。因此,您编写的代码创建了所有三个并行运行的线程,但每次只允许一个线程运行以下代码

int *id = (int *)arg;

printf("My ID is %d\n" , *id);

这里
id
指向所有线程的同一个主变量
i

int *id = (int *)arg;

printf("My ID is %d\n" , *id);
但是变量
i
不断被线程后面
main
中的两个
for
-循环更新。因此,在线程到达
printf
点之前,
i
的值以及
*id
的值可能已经更改

有几种方法可以解决这个问题。最佳方法取决于用例:

  • 在修改
    i
    或使其超出范围之前,请在
    main
    中等待,直到线程发出信号表示它已复制了
    *id
  • 声明并初始化一个数组,
    int-thread\u-id[]
    ,并创建如下线程:
    pthread_create(&tid[i],NULL,func,&thread_id[i])
  • malloc
    一些内存,并使用
    i
    的副本对其进行初始化:

    int *thread_id = malloc(sizeof(*thread_id));
    *thread_id = i
    pthread_create(&tid[i], NULL, func, thread_id);
    
    只是别忘了在使用完线程后释放线程中的内存。或者在
    main
    中,如果线程无法启动

  • 如果
    i
    适合
    void*
    则可以将其内容作为参数直接传递给线程。为了确保它合适,您可以将其声明为
    intptr\t
    ,而不是
    int
    (我们基本上滥用了指针只不过是神奇整数的事实):

    void*func(void*arg){
    pthread_mutex_lock(&mutex);
    //这里我们将指针值解释为整数值
    intptr_t id=(intptr_t)arg;
    printf(“我的ID是%d\n”,(int)ID);
    pthread_mutex_unlock(&mutex);
    }
    int main(){
    intptr\t i;
    pthread_t tid[3];
    //让我们创建三个线程
    对于(i=0;i<3;i++){
    //这里我们把'i'的整数值压缩成
    //应该拿着一个指针
    pthread_create(&tid[i],NULL,func,(void*)i);
    }
    对于(i=0;i<3;i++){
    pthread_join(tid[i],NULL);
    }
    //这不属于这里!!
    //pthread_exit(NULL);
    返回0;
    }
    

  • 这里
    id
    指向所有线程的同一个主变量
    i

    int *id = (int *)arg;
    
    printf("My ID is %d\n" , *id);
    
    但是变量
    i
    不断被线程后面
    main
    中的两个
    for
    -循环更新。因此,在线程到达
    printf
    点之前,
    i
    的值以及
    *id
    的值可能已经更改

    有几种方法可以解决这个问题。最佳方法取决于用例:

  • 在修改
    i
    或使其超出范围之前,请在
    main
    中等待,直到线程发出信号表示它已复制了
    *id
  • 声明并初始化一个数组,
    int-thread\u-id[]
    ,并创建如下线程:
    pthread_create(&tid[i],NULL,func,&thread_id[i])
  • malloc
    一些内存,并使用
    i
    的副本对其进行初始化:

    int *thread_id = malloc(sizeof(*thread_id));
    *thread_id = i
    pthread_create(&tid[i], NULL, func, thread_id);
    
    只是别忘了在使用完线程后释放线程中的内存。或者在
    main
    中,如果线程无法启动

  • 如果
    i
    适合
    void*
    则可以将其内容作为参数直接传递给线程。为了确保它合适,您可以将其声明为
    intptr\t
    ,而不是
    int
    (我们基本上滥用了指针只不过是神奇整数的事实):

    void*func(void*arg){
    pthread_mutex_lock(&mutex);
    //这里我们将指针值解释为整数值
    intptr_t id=(intptr_t)arg;
    printf(“我的ID是%d\n”,(int)ID);
    pthread_mutex_unlock(&mutex);
    }
    int main(){
    intptr\t i;
    pthread_t tid[3];
    //让我们创建三个线程
    对于(i=0;i<3;i++){
    //这里我们把'i'的整数值压缩成
    //应该拿着一个指针
    pthread_create(&tid[i],NULL,func,(void*)i);
    }
    对于(i=0;i<3;i++){
    pthread_join(tid[i],NULL);
    }
    //这不属于这里!!
    //pthread_exit(NULL);
    返回0;
    }
    

  • 实际上,存在一个竞争条件:
    main()
    的局部变量
    i
    在没有fir的情况下递增(通过
    main()
    中的for循环)