C 练习在同一参数上同时使用线程

C 练习在同一参数上同时使用线程,c,linux,multithreading,unix,pthreads,C,Linux,Multithreading,Unix,Pthreads,我正在练习用C语言(Linux操作系统)使用多线程。我写了一个简单的代码来寻找一个数字的除数,如果这个数字没有除数(不包括1和数字本身),那么它就是一个素数。 find_div函数在循环中检查从线程创建运行的数字是否有任何除数。 我的问题是,这两个线程是分开运行的。我尝试过拆分号码,但显然该方法会删除选项(因为发送的号码不是原始号码)。还尝试为循环运行使用全局索引(虽然每个线程在递增时都会使用“新”索引,但由于同步问题而无法工作)。 我不知道如何继续,希望得到一些提示和提示,告诉我应该如何继续(


我正在练习用C语言(Linux操作系统)使用多线程。我写了一个简单的代码来寻找一个数字的除数,如果这个数字没有除数(不包括1和数字本身),那么它就是一个素数。
find_div
函数在循环中检查从线程创建运行的数字是否有任何除数。
我的问题是,这两个线程是分开运行的。我尝试过拆分号码,但显然该方法会删除选项(因为发送的号码不是原始号码)。还尝试为循环运行使用全局索引(虽然每个线程在递增时都会使用“新”索引,但由于同步问题而无法工作)。
我不知道如何继续,希望得到一些提示和提示,告诉我应该如何继续(或者是否有办法让全局索引方法工作?)。
守则:

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

int prime, i;

void *find_div(void *f);

void main(int argc, char* argv[]){
    if(argc < 2){
        fprintf(stderr, "Must enter one number\n");
        exit(1);
    }

    int n;
    pthread_t thread[2];

    prime = 0; //Initialize
    n = atoi(argv[1]);

    if((pthread_create(&thread[0], NULL, find_div, (void *)n)) != 0){
        perror("thread");
        exit(1);
    }

    if((pthread_create(&thread[1], NULL, find_div, (void *)n)) != 0){
        perror("thread");
        exit(1);
    }

    pthread_join(thread[0], NULL);
    pthread_join(thread[1], NULL);

    if(prime == 0)
        fprintf(stdout, "%d is prime number\n", n);
    else
        fprintf(stdout, "\n");
}

void *find_div(void *f){
    for (i=2; i<(int)f; i++){ //Start from 2 since 1 is a divisor to all Natural numbers (and every Natural number is a divisor to itself)
        if ((int)f%i == 0){
            printf("%d ", i);
            prime = 1; //Meaning not prime number
        }
    }
}

您可以用这种方式实现它。将两个参数而不是一个参数传递给
find_div
函数。第二个参数应该是螺纹号。为此,您可以使用和数组
int param[2]
其中
param[0]
将具有
n
并且
param[1]
将具有线程编号。然后
find_div
可以通过以下方式实现:

void *find_div(void *f){

    int num = ((int*)f)[0];
    int tid = ((int*)f)[1];
    int start, end;

    if(tid == 0)
    {
        start = 2;
        end = num/2;
    }
    else
    {
        start = num/2;
        end = num;
    }

    for (i=start; i<end; i++){ //Start from 2 since 1 is a divisor to all Natural numbers (and every Natural number is a divisor to itself)

        if (num%i == 0){

            printf("%d ", i);

            prime = 1; //Meaning not prime number

        }

    }

}
然后在线程函数中,可以使用如下参数

void *find_div(void *f){

    struct MyData *pData = ((MyData*)f);
    int tid = pData->num;
    char chrData = pData->chr;

// ... rest of the code
}

希望这将帮助您完成所需的操作。

我尝试创建一个结构来包含根据收到的答案需要传递的参数-使用线程ID没有成功。但是这个方法让我想到了如何解决这个问题(尽管这不是一个理想的方法):

#包括
#包括
#包括
整型素数=0,除数=0;
void*find_div1(void*s);
void*find_div2(void*s);
void main(int argc,char*argv[]){
如果(argc<2){
fprintf(stderr,“必须输入一个数字”);
出口(1);
}
int n;
pthread_t线程[2];
n=atoi(argv[1]);
if((pthread_create(&thread[0],NULL,find_div1,(void*)n))!=0){
佩罗尔(“线程”);
出口(1);
}
if((pthread_create(&thread[1],NULL,find_div2,(void*)n))!=0){
佩罗尔(“线程”);
出口(1);
}
pthread_join(线程[0],NULL);
pthread_join(线程[1],NULL);//等待两个线程都完成
如果(素数==0)
fprintf(stdout,“%d是素数\n”,n);
其他的
fprintf(标准输出,“\n”);
}
void*find_div1(void*s){
int num=(int)s;
int开始,结束,i;
if(num<4)
返回;
开始=2;
end=num/2;
对于(i=开始;iid;
int开始,结束,i;
如果(tid=‘a’){
开始=2;
end=num/2;
}
否则{
开始=num/2;
end=num;
}

对于(i=start;iToo代码中的空气太少会导致阅读困难,但空气太多也是如此。Re,“[it]因为同步问题而无法工作。”如果您修复了这些问题会发生什么情况?@SolomonSlow我认为它会工作,但我问了一些提示,因为我无法想出如何执行它的方法您的
查找div(…)
取决于只在两个线程中被调用。最好将线程数作为函数的参数。如果
find_div(…)
根本不了解线程,那就更好了:与其告诉它,“你是N中的i号工作者”,不如告诉它,“从这里开始搜索,到了那里就停止搜索。"@SolomonSlow完全同意,但我没有足够的时间来讨论这么多细节。欢迎您演示这种方法。@ashutshraghuwanshi您能解释一下如何通过线程创建传递参数吗?我尝试了一个结构,但没有成功。@S.Arkab
struct
是将参数传递给thre的最佳方式广告。我只能根据你所写的问题代码猜测它为什么对你不起作用。让我编辑我的答案来讨论它。@AshutoshRaghuwanshi感谢你的详细解释和示例!帮助了我很多。
void *find_div(void *f);

struct MyData {
  int num;
  char chr;
};

void main(int argc, char* argv[]){

//... initial code 

    struct MyData data;
    data.num = 10;
    data.chr = 'a';
    pthread_t thread[2];

    if((pthread_create(&thread[0], NULL, find_div, (void *)&data)) != 0){
        perror("thread");
        exit(1);
    }

    //... rest of code
}
void *find_div(void *f){

    struct MyData *pData = ((MyData*)f);
    int tid = pData->num;
    char chrData = pData->chr;

// ... rest of the code
}
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

int prime = 0, divisor = 0;

void *find_div1(void *s);
void *find_div2(void *s);

void main(int argc, char* argv[]){
    if(argc < 2){
        fprintf(stderr, "Must enter one number\n");
        exit(1);
    }
    
    int n;
    pthread_t thread[2];
    n = atoi(argv[1]);

    if((pthread_create(&thread[0], NULL, find_div1, (void *)n)) != 0){
        perror("thread");
        exit(1);
    }

    if((pthread_create(&thread[1], NULL, find_div2, (void *)n)) != 0){
        perror("thread");
        exit(1);
    }

    pthread_join(thread[0], NULL);
    pthread_join(thread[1], NULL); //Wait for both threads to finish

    if(prime == 0)
        fprintf(stdout, "%d is prime number\n", n);
    else
        fprintf(stdout, "\n");
}

void *find_div1(void *s){
    int num = (int)s;
    int start, end, i;
    
    if(num < 4)
        return;

    start = 2;
    end = num/2;

    for (i=start; i<end; i++){ 
        if (num%i == 0){
            if(divisor == 0){
                divisor = 1;
                fprintf(stdout, "Divisors of %d:\n", num);
            }
            printf("%d\n", i);
            prime = 1; //Meaning not prime number
        }
    }
}

void *find_div2(void *s){
    int num = (int)s;
    int start, end, i;

    if(num < 4)
        return;

    start = num/2;
    end = num;

    for (i=start; i<end; i++){ 
        if (num%i == 0){
            if(divisor == 0){
                divisor = 1;
                fprintf(stdout, "Divisors of %d:\n", num);
            }
            printf("%d\n", i);
            prime = 1; 
        }
    }
}
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

int prime = 0, divisor = 0;

void *find_div(void *s);

struct my_args{
    int num;
    char id; //Will identify the thread running
};

void main(int argc, char* argv[]){
    if(argc < 2){
        fprintf(stderr, "Must enter one number\n");
        exit(1);
    }
    
    struct my_args arg1, arg2;

    arg1.num = atoi(argv[1]);
    arg1.id = 'a';
    arg2.num = atoi(argv[1]);
    arg2.id = 'b';

    pthread_t thread[2];

    if((pthread_create(&thread[0], NULL, find_div, (void *)&arg1)) != 0){
        perror("thread");
        exit(1);
    }

    if((pthread_create(&thread[1], NULL, find_div, (void *)&arg2)) != 0){
        perror("thread");
        exit(1);
    }

    pthread_join(thread[0], NULL);
    pthread_join(thread[1], NULL); //Wait for both threads to finish

    if(prime == 0)
        fprintf(stdout, "%d is prime number\n", atoi(argv[1]));
    else
        fprintf(stdout, "\n");
}

void *find_div(void *s){
    struct my_args *pArg = (struct my_args *)s;
    int num = pArg->num;
    char tid = pArg->id;

    int start, end, i;

    if(tid == 'a'){
        start = 2;
        end = num/2;
    }
    else{
        start = num/2;
        end = num;
    }

    for (i=start; i<end; i++){ //Start from 2 since 1 is a divisor to all Natural numbers (and every Natural number is a divisor to itself)
        if (num%i == 0){
            if(divisor == 0){
                fprintf(stdout, "Divisors of %d:\n", num);
                divisor = 1;
            }
            printf("%d\n", i);
            prime = 1; //Meaning not prime number
        }
    }
}