首页 > 解决方案 > C 中的多线程 - 最终创建的线程超过其他线程的输出?

问题描述

我是 C 的初学者,正在尝试多线程。我编写了一个程序来尝试通过使用多个线程来计算欧拉 phi 函数的值。我正在使用蛮力,检查每个小于给定输入的单个数字的共同因素。

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

int has_common_factor(int number1, int number2);

void *phi_function(void *);
pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
int out = 0;
int NTHREADS,inp;

int main(int argc, char *argv[])
{
    int c = 0;
    while(1){
        c = getopt(argc, argv, "p:n:");
        if (c == -1){
            break;
        }
        switch(c){
            case 'p': inp = atoi(optarg);
                break;
            case 'n': NTHREADS = atoi(optarg);
                break;
            default: printf("Invalid Option");
                return 1;
        }
    }
    //pthread_t thread_id[NTHREADS];
    pthread_t *thread_id;
    thread_id = (pthread_t *)malloc(sizeof(pthread_t) * NTHREADS);
    int i, j, arg;

    for (i = 0; i < NTHREADS; i++)
    {
        arg = i * inp / NTHREADS + 1;
        pthread_create(&thread_id[i], NULL, phi_function, (void *)&arg);
    }

    for (j = 0; j < NTHREADS; j++)
    {
        pthread_join(thread_id[j], NULL);
    }

    printf("Final value: %d\n", out);
}

void *phi_function(void *ptr)
{
    printf("threadid: %ld\n",pthread_self());
    int i;
    int *min;
    min = (int *)ptr;
    FILE *fptr;
    sleep(*min);
    char filename[100];
    sprintf(filename,"output%d", *min);

    fptr = fopen(filename,"w");

    for (i = *min; i < *min + inp / NTHREADS; i++)
    {
        int j;

        if (has_common_factor(i, inp) == 0) {
            pthread_mutex_lock(&mutex1);
            out++;
            printf("i = %d\n",i);
            pthread_mutex_unlock(&mutex1);
            fprintf(fptr,"i = %d\n",i);

        }
    }
    fclose(fptr);
}

int has_common_factor(int number1, int number2) {
    int j;
    for (j=2; j<=number1; j++) {
        if (number1 %j == 0 && number2 %j ==0) {
            return 1;
        }
    }
    return 0;
}

我通过将输入分成 N 个不同的大小相等的范围来使用线程,并让 N 个线程中的每一个线程检查每个范围是否有相对质数的整数。我还打印了所有检测到的相对素数,以检查是否有任何错误。该程序适用于 1 个整数,为我检查的所有数字提供正确的输出,但是当使用超过 1 个线程时会发生一些有趣的事情。

用两个线程编译和运行后,使用 2 个线程和 20 的输入,像这样:

./thread -p 20 -n 2

这是输出:

threadid: 140235244418816
threadid: 140235236026112
i = 11
i = 13
i = 17
i = 19
i = 11
i = 13
i = 17
i = 19
Final value: 8

如您所见,它获得了相对质数整数的正确计数,但仅输出在第二个线程范围内检测到的整数,似乎覆盖了第一个线程。由于有两个唯一的线程 ID,因此两个线程都必须已运行。使用 1 个线程会产生以下输出:

threadid: 140235236026112
i = 1
i = 3
i = 7
i = 9
i = 11
i = 13
i = 17
i = 19
Final value: 8

发生了什么/我能做些什么来解决这个问题?

标签: cmultithreading

解决方案


for (i = 0; i < NTHREADS; i++)
{
    arg = i * inp / NTHREADS + 1;
    pthread_create(&thread_id[i], NULL, phi_function, (void *)&arg);
}

您将相同的参数 , 传递&arg给每个线程。您需要将不同的参数传递给每个线程。

一个很好的使用模式是:

  1. 调用malloc以分配对象以保存线程的参数。
  2. 填写结构。
  3. 调用pthread_create,将您从中获得的值传递给它malloc
  4. 在线程中,从结构中提取值,并free在完成后提取它。

这可确保您将不同的值传递给每个线程。


推荐阅读