我正在尝试用C语言构建一个简单的计算器,代码如下…
#include<stdio.h>
#include<pthread.h>
#include<stdlib.h>
typedef struct Calc {
int a,b;
}C;
void *add(void* arg) {
C* temp = (Calc *)arg;
int ans= temp->a + temp->b;
printf("Sum is %dn",ans);
return NULL;
}
void *sub(void* arg) {
C* temp = (Calc *)arg;
int ans= temp->a - temp->b;
printf("Sub is %dn",ans);
return NULL;
}
void *mul(void* arg) {
C* temp = (Calc *)arg;
int ans= temp->a * temp->b;
printf("mul is %dn",ans);
return NULL;
}
void *div(void* arg) {
C* temp = (Calc *)arg;
int ans= temp->a / temp->b;
printf("div is %dn",ans);
return NULL;
}
int main() {
pthread_t t1, t2, t3, t4;
C* calc = (Calc *)malloc(sizeof(C));
calc->a = 7;
calc->b = 4;
pthread_create(&t1,NULL,add(calc),NULL);
pthread_create(&t2,NULL,sub(calc),NULL);
pthread_create(&t3,NULL,mul(calc),NULL);
pthread_create(&t4,NULL,div(calc),NULL);
return 0;
}
和我得到了一个错误,每次调用函数的Ex..
argument of type "void *" is incompatible with parameter of type "void *(*)(void *)"
40 | pthread_create(&t2,NULL,sub(calc),NULL);
| ~~~^~~~~~
| |
| void*
谁能告诉我错误是什么以及如何解决它?谢谢你:)
大致总结一下注释:
首先,线程对于这种类型的程序来说肯定是多余的,但是在某处开始学习是很好的。
为你的结构类型决定一个标识符(对Calc
的引用应该是C
或struct Calc
)。
也就是说,没有必要显式地将void *
转换为另一种指针类型—在赋值期间隐式地和安全地处理。例如,
C *temp = arg;
和
C *calc = malloc(sizeof *calc);
都可以,并且是首选。
C
是一个非常糟糕的类型标识符;
pthread_create(&t1, NULL, add(calc), NULL);
你正在尝试调用add
(其参数类型不正确),并将该函数的结果作为第三个参数传递给pthread_create
。
pthread_create
需要一个签名为void *(*)(void *)
的函数指针作为它的第三个参数。这个函数被用作线程的入口点;也称为start例程。
第四个参数应该是一个void *
,它是传递给线程启动例程的指针。
在程序的main
函数退出之前,你的线程可能没有完成它们的执行。要等待一个线程结束,可以使用pthread_join
,它以一个线程作为第一个参数,并以void **
作为第二个参数——一个存储指针的位置,而不是从线程的start例程(或者更具体地说,是pthread_exit
函数)返回的指针。
pthread_join(t1, NULL);
此函数将阻止调用的线程执行,直到指定的线程完成。如果指定的线程已经完成,pthread_join
立即返回。
这是程序的最小版本,只有一个add
线程要关注。注意,在这个例子中,动态分配内存基本上是不必要的。
#include <pthread.h>
#include <stdio.h>
typedef struct {
int a;
int b;
} Calculator;
void *add(void *arg) {
Calculator *temp = arg;
int ans = temp->a + temp->b;
printf("Sum is %dn", ans);
return NULL;
}
int main(void) {
pthread_t t1; /* ...and so on */
Calculator calc = { .a = 7, .b = 4 };
pthread_create(&t1, NULL, add, &calc);
/* ...and so on */
pthread_join(t1, NULL);
/* ...and so on */
}
只需复制pthread_create
和pthread_join
函数,使用不同的线程并启动例程来扩展它。注意,如果需要并发性,所有对pthread_create
的调用都应该发生在对pthread_join
的调用之前。
请注意,pthread_create
和pthread_join
都使用它们的返回值来表示成功或失败(0
表示成功,否则为错误编号)。
检查这些值是否有错误是明智的(使用strerror
来获取可打印的字符串)。
int main()
应该是int main(void)
,或int main(int argc, char **argv
(或同等)。- 标准库中有一个
div
函数。为避免冲突,您需要使用不同的名称。