使用线程构建一个简单的计算器
Build a simple calculator using threads
我正在尝试使用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 %d\n",ans);
return NULL;
}
void *sub(void* arg) {
C* temp = (Calc *)arg;
int ans= temp->a - temp->b;
printf("Sub is %d\n",ans);
return NULL;
}
void *mul(void* arg) {
C* temp = (Calc *)arg;
int ans= temp->a * temp->b;
printf("mul is %d\n",ans);
return NULL;
}
void *div(void* arg) {
C* temp = (Calc *)arg;
int ans= temp->a / temp->b;
printf("div is %d\n",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 routine.
第四个参数应该是一个void *
,它是传递给线程启动例程的指针。
您的线程可能无法在程序的 main
函数退出之前完成执行。要等待线程完成,您可以使用 pthread_join
,它将线程作为其第一个参数,并将 void **
作为其第二个参数 - 一个存储指针的位置而不是 return从线程的启动例程(或更具体地说,pthread_exit
函数)编辑。
pthread_join(t1, NULL);
此函数将阻止调用线程 的执行,直到指定的线程完成。如果指定的线程已经完成,pthread_join
return 立即。
这是您程序的最小版本,只有一个 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 %d\n", 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
都使用它们的 return 值来表示成功或失败(0
表示成功,否则为错误编号)。
最好检查这些值是否有错误(使用 strerror
获取可打印的字符串)。
更多附录:
int main()
实际上应该是 int main(void)
,或 int main(int argc, char **argv
(或等价物)。
- 标准库中有一个
div
函数。为避免冲突,您需要使用不同的名称。
我正在尝试使用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 %d\n",ans);
return NULL;
}
void *sub(void* arg) {
C* temp = (Calc *)arg;
int ans= temp->a - temp->b;
printf("Sub is %d\n",ans);
return NULL;
}
void *mul(void* arg) {
C* temp = (Calc *)arg;
int ans= temp->a * temp->b;
printf("mul is %d\n",ans);
return NULL;
}
void *div(void* arg) {
C* temp = (Calc *)arg;
int ans= temp->a / temp->b;
printf("div is %d\n",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 routine.
第四个参数应该是一个void *
,它是传递给线程启动例程的指针。
您的线程可能无法在程序的 main
函数退出之前完成执行。要等待线程完成,您可以使用 pthread_join
,它将线程作为其第一个参数,并将 void **
作为其第二个参数 - 一个存储指针的位置而不是 return从线程的启动例程(或更具体地说,pthread_exit
函数)编辑。
pthread_join(t1, NULL);
此函数将阻止调用线程 的执行,直到指定的线程完成。如果指定的线程已经完成,pthread_join
return 立即。
这是您程序的最小版本,只有一个 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 %d\n", 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
都使用它们的 return 值来表示成功或失败(0
表示成功,否则为错误编号)。
最好检查这些值是否有错误(使用 strerror
获取可打印的字符串)。
更多附录:
int main()
实际上应该是int main(void)
,或int main(int argc, char **argv
(或等价物)。- 标准库中有一个
div
函数。为避免冲突,您需要使用不同的名称。