为什么使用线程时我的程序输出总是不同?

时间:2022-07-25 20:59:15

My program's desired functionality:
Using the command line user inputs N and M. N is the number of new threads that will be created and M is the number of how much every thread increments the global variable A.

我的程序所需的功能:使用命令行用户输入N和M. N是将要创建的新线程的数量,M是每个线程增加全局变量A的数量。

This is my code:

这是我的代码:

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

static int A = 0;

void *Thread(void* x){
        int i;
        int n = *((int*)x);
        for (i = 0; i<n; i++){
                A++;
        }
}

int main(int argc, char* argv[]){
        int i;
        int N = atoi(argv[1]);
        int M = atoi(argv[2]);

        pthread_t *thread = (pthread_t *) malloc(sizeof(pthread_t)*N);

        if(!thread){
                printf("No memory\n");
                exit(2);
        }

        for (i = 0; i< N; i++){
                if (pthread_create(&thread[i], NULL, Thread, &M)){
                        printf("Not able to create a thread\n");
                        exit(1);
                }
        }

        for(i = 0; i< N; i++)
                pthread_join(thread[i], NULL);

        printf("A = %d\n", A);

        return 0;
}

The problem is that every time I run it there's a different output. Screenshot of my terminal when i run the program multiple times in a row

问题是每次运行它都有不同的输出。连续多次运行程序时终端的屏幕截图

1 个解决方案

#1


3  

The problem is that you are creating multiple threads that in parallel are trying to modify your static A global variable at the same time, without any kind of protection.

问题是你正在创建多个线程并行尝试同时修改静态A全局变量,而没有任何保护。

That means that depending on the scheduling of the threads, the changes on your global variable will not be atomic, producing this effect.

这意味着根据线程的调度,全局变量的更改将不是原子的,从而产生这种效果。

You can solve this with a mutex, declare it with:

您可以使用互斥锁解决此问题,并使用以下命令声明:

pthread_mutex_t mutex;

And initialise / release it with pthread_mutex_init and pthread_mutex_destroy.

并使用pthread_mutex_init和pthread_mutex_destroy初始化/释放它。

Inside of the thread, before doing the change protect the resource to change with pthread_mutex_lock, and release it with pthread_mutex_unlock. So the code will be changed like this:

在线程内部,在执行更改之前保护资源以使用pthread_mutex_lock进行更改,并使用pthread_mutex_unlock释放它。所以代码会像这样改变:

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

static int A = 0;
pthread_mutex_t mutex;


void *Thread(void* x){
        int i;
        int n = *((int*)x);

        pthread_mutex_lock(&mutex);
        A += n;
        pthread_mutex_unlock(&mutex);
}

int main(int argc, char* argv[]){
        int i;
        int N = atoi(argv[1]);
        int M = atoi(argv[2]);

        pthread_mutex_init(&mutex, NULL);
        pthread_t *thread = (pthread_t *) malloc(sizeof(pthread_t)*N);

        if(!thread){
                printf("No memory\n");
                exit(2);
        }

        for (i = 0; i< N; i++){
                if (pthread_create(&thread[i], NULL, Thread, &M)){
                        printf("Not able to create a thread\n");
                        exit(1);
                }
        }

        for(i = 0; i< N; i++)
                pthread_join(thread[i], NULL);

        printf("A = %d\n", A);

        pthread_mutex_destroy(&mutex);

        return 0;
}

#1


3  

The problem is that you are creating multiple threads that in parallel are trying to modify your static A global variable at the same time, without any kind of protection.

问题是你正在创建多个线程并行尝试同时修改静态A全局变量,而没有任何保护。

That means that depending on the scheduling of the threads, the changes on your global variable will not be atomic, producing this effect.

这意味着根据线程的调度,全局变量的更改将不是原子的,从而产生这种效果。

You can solve this with a mutex, declare it with:

您可以使用互斥锁解决此问题,并使用以下命令声明:

pthread_mutex_t mutex;

And initialise / release it with pthread_mutex_init and pthread_mutex_destroy.

并使用pthread_mutex_init和pthread_mutex_destroy初始化/释放它。

Inside of the thread, before doing the change protect the resource to change with pthread_mutex_lock, and release it with pthread_mutex_unlock. So the code will be changed like this:

在线程内部,在执行更改之前保护资源以使用pthread_mutex_lock进行更改,并使用pthread_mutex_unlock释放它。所以代码会像这样改变:

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

static int A = 0;
pthread_mutex_t mutex;


void *Thread(void* x){
        int i;
        int n = *((int*)x);

        pthread_mutex_lock(&mutex);
        A += n;
        pthread_mutex_unlock(&mutex);
}

int main(int argc, char* argv[]){
        int i;
        int N = atoi(argv[1]);
        int M = atoi(argv[2]);

        pthread_mutex_init(&mutex, NULL);
        pthread_t *thread = (pthread_t *) malloc(sizeof(pthread_t)*N);

        if(!thread){
                printf("No memory\n");
                exit(2);
        }

        for (i = 0; i< N; i++){
                if (pthread_create(&thread[i], NULL, Thread, &M)){
                        printf("Not able to create a thread\n");
                        exit(1);
                }
        }

        for(i = 0; i< N; i++)
                pthread_join(thread[i], NULL);

        printf("A = %d\n", A);

        pthread_mutex_destroy(&mutex);

        return 0;
}