我在这里看了很多关于我的问题的答案,但没有人回答我面临的问题。
我正在用C编写一个多线程程序来执行矩阵乘法来评估系统性能。
目前我只是尝试在传递几个变量时启动单个线程。
这是我的代码
pthread_t *thread = (pthread_t *) malloc(sizeof(pthread_t));
int a = malloc(sizeof(int));
int b = malloc(sizeof(int));
a = 0;
b = size;
void **args = (void **) malloc(2 * sizeof(void *));
args[0] = (void *)a;
args[1] = (void *)b;
pthread_create(&thread[0], NULL, matrixMath, &args);
matrixMath方法:
void* matrixMath(void* args) {
int start = *((int *)args[0]);
int end = *((int *)args[1]);
printf("Start: %d, End: %d\n", start, end);
return NULL;
}
每当我尝试编译时,我在“int start”和“int end”声明中都得到“无效使用void表达式”。我基于the discussion found here这些行。有什么帮助吗?
答案 0 :(得分:2)
由于args
是void *
,因此您无法取消引用它,但args[0]
会在应用(int *)
强制转换之前尝试取消引用它。因此,您需要重新表示,以便在取消引用之前将void *
转换为int *
:
int start = ((int *)args)[0];
int end = ((int *)args)[1];
或者(但等效地):
int *array = (int *)args; // You could skip the cast in C
int start = args[0];
int end = args[1];
我对&args
的调用中的pthread_create()
也不相信。这会将void ***
传递给线程代码。我认为你需要更像这样的东西,它有许多优点,包括更简单:
pthread_t thread;
int *a = malloc(2 * sizeof(int));
a[0] = 0;
a[1] = size;
pthread_create(&thread, NULL, matrixMath, a);
你甚至可以使用:
pthread_t thread;
int a[] = { 0, size };
pthread_create(&thread, NULL, matrixMath, a);
答案 1 :(得分:1)
我将使用struct
演示替代方法。随着时间的推移,这种替代方法更容易编码和维护。
您的代码存在一些可能导致编译器和运行时错误的问题,以下是一些应该指向正确路径的示例:
您的int
作业未执行您可能想要或打算执行的任务。
你的代码将指针地址的数值赋给一个整数,可能由于可变的大小差异而截断数据......你可能想要的是存储指向int的指针。
您写道:
int a = malloc(sizeof(int));
int b = malloc(sizeof(int));
你可能想写:
int * a = malloc(sizeof(int));
int * b = malloc(sizeof(int));
您的代码将void *
视为void **
(或int *
),而不使用任何广告...
您写道:
int start = *((int *)args[0]);
int end = ((int *)args)[1];
你可能想写:
int start = ( (int *)args )[0];
int end = ( (int *)args )[1];
您的代码执行malloc
三(3)次,但从不调用free
(您有内存泄漏)。
如果您定义一个struct
来包含您想要的数据并移动"将会更容易。 (或与之分享)。
例如,以下 未经测试的 代码可能不起作用,但它清楚地显示了如何使用struct
进行数据传输的概念更易于管理,维护和更新。它还需要较少的malloc
调用,使内存管理更容易。
struct ThreadData {
int start;
int end;
};
void * thread_task(void *);
int main(void) {
struct ThreadData * data = malloc(sizeof(*data));
data->start = 0;
data->end = 0; // = size;
pthread_t thr;
pthread_create(&thr, NULL, thread_task, data);
// ... do whatever.
// ... remember to join thread
}
void * thread_task(void * _data) {
struct ThreadData * data = _data;
printf("Start: %d, End: %d\n", data->start, data->end);
// remember to free the memory when you're done.
free(data);
return NULL;
}
这种方法更容易编码和维护。此外,当您需要为新线程添加数据时,它很简单 - 只需更新结构。
您甚至可以将复杂的返回值放回结构中的占位符中,从而允许线程执行更复杂的任务(请记住避免让多个线程写入同一个struct
字段)。 / p>