c - 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
发生了什么/我能做些什么来解决这个问题?
解决方案
for (i = 0; i < NTHREADS; i++)
{
arg = i * inp / NTHREADS + 1;
pthread_create(&thread_id[i], NULL, phi_function, (void *)&arg);
}
您将相同的参数 , 传递&arg
给每个线程。您需要将不同的参数传递给每个线程。
一个很好的使用模式是:
- 调用
malloc
以分配对象以保存线程的参数。 - 填写结构。
- 调用
pthread_create
,将您从中获得的值传递给它malloc
。 - 在线程中,从结构中提取值,并
free
在完成后提取它。
这可确保您将不同的值传递给每个线程。
推荐阅读
- r - 可以将图例大小设置为自动吗?(ggplot2)
- amazon-web-services - ECS:强制服务在同一个 EC2 实例上运行
- guidewire - 如何更改 Guidewire ClaimCenter 10 中的实体验证警告
- python - 仅删除列表中出现的第一个实例
- php - 相互比较两个项目时出现PHP错误
- javascript - React Native 监听元素的位置
- java - 当输入包含空格时如何使用replaceAll
- android - 从 Android 中的联系人中提取详细信息时获取错误数据
- qt - Qt Quick QML Flickable 禁用轻弹并仅启用滚动
- maven - 无法在 oracle weblogic 12.1.3 中发布 EAR