在Centos7里,编写多线程的入栈出栈时,出现这样错误提示:
图片版:
文字版:
[root@CentOs7 05-xitongbiancheng]# gcc 05-24-01.pthread-cancel-pop-push.c -pthread 05-24-01.pthread-cancel-pop-push.c: 在函数‘func’中: 05-24-01.pthread-cancel-pop-push.c:47:1: 错误:expected ‘while’ before ‘int’ int main(void) ^ 05-24-01.pthread-cancel-pop-push.c:79:1: 错误:expected declaration or statement at end of input } ^ 05-24-01.pthread-cancel-pop-push.c:79:1: 错误:expected declaration or statement at end of input
分析一: 看提示很明显,是语法错误,某个地方缺少“}”了,但是,进过仔细查看,括号都是成对出现的。
分析二: 用 grep 统计括号数量也是对的,如下图:
图片版:
文字版:
[root@CentOs7 05-xitongbiancheng]# grep -c "(" 05-24-01.pthread-cancel-pop-push.c 24 [root@CentOs7 05-xitongbiancheng]# grep -c ")" 05-24-01.pthread-cancel-pop-push.c 24 [root@CentOs7 05-xitongbiancheng]# grep -c "{" 05-24-01.pthread-cancel-pop-push.c 5 [root@CentOs7 05-xitongbiancheng]# grep -c "}" 05-24-01.pthread-cancel-pop-push.c 5
分析三:有人会说是隐藏的乱码。
用 cat -e 命令,打印文本,看报错行,也没有什么乱码。
cat -e 05-24-01.pthread-cancel-pop-push.c
分析四:是不是某行结尾有什么多余的字符,比如 \t 制表符之类的。
结尾除了回车换行,每行结尾的 空格、制表符都删了。
分析五: 代码之前编译运行都没问题,是加上 pthread_cleanup_push( push_func, p); 这段出现的报错。
注释掉 这行,就又正常了。但仔细看了代码,没有发现任何语法、拼写错误。
------》》》》 从出现问题时,是14点多,到16点,苦思冥想,没有解决方法,休息一下,眼睛疼
------》》》》 家务处理完后,21点又到电脑前,接续:
分析六: 突然解决
本来想放弃的,但是又翻了翻代码,突然想起,课程中说,入栈和出栈要在同一层代码成对出现。
注意看,
下面完整源码,第36行,pop 被注释掉了(当时写第30行 push 的那段代码时为了方便调试,就把 pop 的注释掉)
结果没想到给自己埋下了雷。
解决方法:就是把 第36行,pop 行取消注释,就可以正常编译成了
编译:
图片版:
文字版:
gcc 05-24-01.pthread-cancel-pop-push.c -pthread
加 -pthread 参数是因为,多线程用的不是系统的库,所以要加上,具体看 man 手册;
在 ubuntu里 则用的是 -lpthread 参数,注意发行版差异这点。
----------- 以下是完整源码 ----------------
1 /* 2 * 练习: 3 * 创建多线程,新线程等待一会,并取消线程,同时设置入栈出栈, 4 * 来保护数据。 5 * 注意: 6 * 在不同发行版的Linux(Ubuntu、CentOS)中,需要的头文件不一样 7 * Date: 8 * 2023/04/06 9 * 10 * */ 11 12 #include <stdio.h> 13 #include <pthread.h> 14 #include <stdlib.h> 15 #include <string.h> 16 17 void push_func( void *arg ) 18 { 19 printf("压栈 push_func 函数执行\n"); 20 } 21 22 void *func(void *arg) 23 { 24 int *p = calloc(1, 4); 25 *p = 1024; 26 27 // 收到线程取消请求,执行入栈(压栈) 28 // 参数1:压栈要执行的指针函数 29 // 参数2:压栈要执行的指针函数参数 30 pthread_cleanup_push( push_func, p); 31 32 printf("这里是 func 函数, ID: %ld\n", pthread_self() ); 33 sleep(5); // 模拟程序处理数据的耗时 34 35 // 出栈 36 //pthread_cleanup_pop(0); 37 38 // 5秒,没有收到取消线程请求,线程会主动退出, 39 // 并设置,退出值 1024 (数字当前是随意写的) 40 //int *p = calloc(1, 4); 41 //*p = 1024; 42 pthread_exit( (void *)p ); 43 } 44 45 46 int main(void) 47 { 48 // 创建新线程 49 pthread_t t_id = -1; 50 pthread_create( &t_id, // 新线程ID 51 NULL, // 线程属性 52 func, // 线程运行指针函数 53 NULL); // 线程运行指针函数的参数 54 55 // 新线程创建后继续执行下面代码 56 printf("这里是 main 函数, ID: %ld\n", pthread_self() ); 57 58 // 取消线程请求 59 sleep(1); 60 printf("准备取消线程!\n"); 61 sleep(0.5); // 等待线程完全创建完,防止线程没有创建完,就取消。 62 pthread_cancel(t_id); 63 64 // 取消线程后,看看能否再结合。(结果是不能结合) 65 int *retval; 66 int ret_tryjoin = pthread_tryjoin_np( t_id, (void *)&retval); // tryjoin 不阻塞,错误直接返回 67 if(ret_tryjoin) 68 { 69 fprintf(stderr, "线程被取消,结合失败!\n返回值:%s\n", strerror(ret_tryjoin) ); 70 } 71 else 72 { 73 printf("线程结合,func 退出值:%d\n", *retval); 74 } 75 76 return 0; 77 }
-
标签:24,出栈,入栈,05,pop,线程,pthread,push,多线程 From: https://www.cnblogs.com/wutou/p/17294314.html