对于素因分解项目,我需要将一个结构和一个数字(从命令行)传递给线程。下面的代码是我到目前为止所拥有的。因数分解工作正常,问题在于传递给线程的索引未按顺序传递,因此结果各不相同,通常将数据存储在后续线程的同一索引中。任何人都知道如何保证线程将访问哪个索引,或者实现此目标的更好方法?每个线程都必须将其数据存储在一个结构中,以便在所有线程关闭后,主线程可以在最后打印所有数据。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <pthread.h>
// Initialize Constants
#define MAX_ARGS 25
#define MAX_PRIMES 10
#define SMALLEST_ARG 2
// Define Struct
struct PrimeData {
int index;
int num_to_fact[MAX_ARGS];
int primes[MAX_ARGS][MAX_PRIMES];
};
// Declare Functions
void* factor (void*);
// Main
int main(int argc, char* argv[])
{
// Initialize Struct Variables
struct PrimeData data;
struct PrimeData* data_addr = &data;
data.index = 0;
for (int i = 0; i < MAX_ARGS; i++)
data.num_to_fact[i] = -1;
for (int i = 0; i < MAX_ARGS; i++) {
for (int j = 0; j < MAX_PRIMES; j++)
data.primes[i][j] = -1;
}
// Check for arguments
if (argc <= 1)
printf("Usage: ./p3 <number to factor>...\n");
else {
// Initialize Thread Handler list
pthread_t threads[argc - 1];
// Create a Thread per Argument
for (int i = 1; i < argc; i++) {
// Update shares structure
data.index = i - 1;
data.num_to_fact[i - 1] = atoi(argv[i]);
// Create thread
pthread_create(&threads[i - 1], NULL, factor, (void*)data_addr);
}
// Tell main to wait for threads to terminate
for (int i = 1; i < argc; i++)
pthread_join(threads[i - 1], NULL);
}
// Iterate through struct
for (int i = 0; i < MAX_ARGS; i++) {
if (data.num_to_fact[i] == -1)
break;
printf("%d: ", data.num_to_fact[i]);
for (int j = 0; j < MAX_PRIMES; j++) {
if (data.primes[i][j] == -1)
break;
printf("%d ", data.primes[i][j]);
}
printf("\n");
}
// Terminate
return 0;
}
// The factor() function
void* factor(void* data)
{
struct PrimeData* d = (struct PrimeData*)data;
int index = d->index;
int n = d->num_to_fact[index];
int counter = 0;
int i = 2;
while (n != 1) {
if (n % i == 0) {
while (n % i == 0) {
d->primes[index][counter] = i;
n = n / i;
counter++;
}
}
i++;
}
return NULL;
}
答案 0 :(得分:0)
您只有一个“结构PrimeData数据;”,因此在pthread_create调用中发信号通知其地址毫无意义。混乱的方式是全球化“ PrimeData”,以便线程可以访问它,对索引进行数组化:“ int index [MAX_ARGS];”,将其加载为0、1、2、3等。然后通过每个线程所需索引的地址,例如'&data_addr [i-1]'。
如果您接受C数组从零开始索引,从而摆脱掉很多这些[i-1]事情,可能会更清楚。
答案 1 :(得分:0)
我使用互斥锁使它正常工作。有点奇怪,我们不会在下一章介绍互斥体。我最终偶然发现一篇文章,其中解释了当您使用多线程时,每个线程都在访问共享内存位置(在本例中为我的结构),那么您必须使用互斥锁控制索引:
// At the start of the program, before main
pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
int _index = -1;
// first three lines of the factor function
pthread_mutex_lock(&mutex1);
_index++;
pthread_mutex_unlock(&mutex1);
答案 2 :(得分:0)
// Define Struct
struct PrimeData {
int num_to_fact[MAX_ARGS];
int primes[MAX_ARGS][MAX_PRIMES];
};
typedef struct Wrapper {
int index;
struct PrimeData *data;
} Wrapper;
...
int main(int argc, char *argv)
{
// ...
// Define wrappers
Wrapper wrappers[argc-1];
for (int i = 1; i < argc; i++)
{
wrappers[i-1].index = i;
wrappers[i-1].data = &data;
//...
pthread_create(&threads[i - 1], NULL, factor, wrappers + i - 1);
}
// ...
}
void *factor(void *wrapper)
{
Wrapper *w = (Wrapper *) wrapper;
struct PrimeData* d = w->data;
int index = w->index;
// ...
}