练习在同一个参数上同时使用线程
Practice using threads simultaneously on same argument
我正在练习C语言中多线程的使用(Linux OS)。我写了一个简单的代码来找到一个数字的约数,如果这个数字没有约数(不包括 1 和数字本身)那么它就是一个素数。
find_div
函数在循环中检查线程创建时 运行 的数字是否有除数。
我的问题是两个线程分别 运行ning。我试过拆分号码,但显然该方法删除了选项(因为发送的号码不是原始号码)。还尝试为循环使用全局索引 运行(认为每个线程在递增时都会使用“新”索引,但由于同步问题而无法正常工作)。
我不知道如何继续,希望得到关于我应该如何推进的提示和提示(或者是否有办法使全局索引方法起作用?)。
代码:
#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
}
}
}
数字为6时的输出:
2 3 2 3
你可以这样实现。将两个参数而不是一个参数传递给 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 *
。在您的代码中,int n;
被传递为 (void *)n
它起作用是因为指针与 int
的大小相同,但这不是正确的方法。正确的方法是传递 (void *)&n
并在线程函数内部将其用作 *(int*)f
。让我演示如何传递结构并使用它。
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
}
希望这会帮助你做你需要做的事情。
我已经尝试创建一个结构来包含需要根据收到的答案传递的参数 - 使用线程 ID 没有成功。但是这个方法让我知道了如何解决这个问题(虽然这不是一个理想的方法):
#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
}
}
}
我正在练习C语言中多线程的使用(Linux OS)。我写了一个简单的代码来找到一个数字的约数,如果这个数字没有约数(不包括 1 和数字本身)那么它就是一个素数。
find_div
函数在循环中检查线程创建时 运行 的数字是否有除数。
我的问题是两个线程分别 运行ning。我试过拆分号码,但显然该方法删除了选项(因为发送的号码不是原始号码)。还尝试为循环使用全局索引 运行(认为每个线程在递增时都会使用“新”索引,但由于同步问题而无法正常工作)。
我不知道如何继续,希望得到关于我应该如何推进的提示和提示(或者是否有办法使全局索引方法起作用?)。
代码:
#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
}
}
}
数字为6时的输出:
2 3 2 3
你可以这样实现。将两个参数而不是一个参数传递给 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 *
。在您的代码中,int n;
被传递为 (void *)n
它起作用是因为指针与 int
的大小相同,但这不是正确的方法。正确的方法是传递 (void *)&n
并在线程函数内部将其用作 *(int*)f
。让我演示如何传递结构并使用它。
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
}
希望这会帮助你做你需要做的事情。
我已经尝试创建一个结构来包含需要根据收到的答案传递的参数 - 使用线程 ID 没有成功。但是这个方法让我知道了如何解决这个问题(虽然这不是一个理想的方法):
#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
}
}
}