线程处理—线程终止
1.相关函数
**线程终止有以下几种方法: **
- **线程函数执行 return 语句; **
- **线程函数内部调用 pthread_exit 函数; **
- 其他线程调用 pthread_cancel 函数。
1.1系统调用pthread_exit
线程终止函数为 pthread_exit:
1 2 3 4 5 6
| #include <pthread.h>
void pthread_exit(void *retval);
|
当某个线程调用 pthread_exit 方法后,该线程会被关闭(相当于 return)。线程 可以通过 retval 向其它线程传递信息,retval 指向的区域不可以放在线程函数的栈内。 其他线程(例如主线程)如果需要获得这个返回值,需要调用 pthread_join 方法。
1.2系统调用pthread_join
1 2 3 4 5 6 7 8 9 10 11 12
| #include <pthread.h>
int pthread_join(pthread_t thread, void **retval);
|
1.3系统调用pthread_detach
1 2 3 4 5 6 7 8 9 10 11 12
| #include <pthread.h>
int pthread_detach(pthread_t thread);
|
1.4系统调用pthread_cancel
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| #include <pthread.h>
int pthread_cancel(pthread_t thread);
|
1.5系统调用pthread_setcancelstate
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| #include <pthread.h>
int pthread_setcancelstate(int state, int *oldstate); 6)pthread_setcanceltype #include <pthread.h>
int pthread_setcanceltype(int type, int *oldtype);
|
2.实例
2.1pthread_join 测试例程
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
|
#include <pthread.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <math.h> #include <string.h>
typedef struct { char *ptr; int len; } Result;
void *thread_red(void *argv) { Result *result1 = (Result *) malloc(sizeof(Result)); char *code = (char *) argv; char *buffer = (char *) malloc(sizeof(char) * 101); while (1) { fgets(buffer, 100, stdin); if (buffer[0] == code[0]) { free(buffer); printf("Red thread exit\n"); char *res = strdup("Red她离开了\n"); result1->ptr = res; result1->len = strlen(res); pthread_exit((void *) result1); } else { printf("Red thread continue\n"); } } }
void *thread_white(void *argv) { Result *result2 = (Result *) malloc(sizeof(Result)); char *code = (char *) argv; char *buffer = (char *) malloc(sizeof(char) * 101); while (1) { fgets(buffer, 100, stdin); if (buffer[0] == code[0]) { free(buffer); printf("White thread exit\n"); char *res = strdup("White她离开了\n"); result2->ptr = res; result2->len = strlen(res); pthread_exit((void *) result2); } else { printf("White thread continue\n"); } } }
int main(int argc, char *argv[]) { pthread_t tid_red; pthread_t tid_white; char red_code = 'r'; char white_code = 'w'; Result *result_red=NULL; Result *result_white=NULL;
pthread_create(&tid_red, NULL, thread_red, &red_code); pthread_create(&tid_white, NULL, thread_white, &white_code);
pthread_join(tid_red,(void **)&result_red); printf("Red的结局%d是:%s\n",result_red->len,result_red->ptr); free(result_red); pthread_join(tid_white,(void **)&result_white); printf("White的结局%d是:%s\n",result_white->len,result_white->ptr); free(result_white); return 0; }
|
2.2pthead_detach测试例程
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| #include <pthread.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h>
void *thread_tid(void *argv) { printf("Thread tid:%lu, started\n", (unsigned long)pthread_self()); sleep(2); printf("Thread finished\n"); return NULL; }
int main(int argc, char *argv[]) { pthread_t tid; int res_pthread_create = pthread_create(&tid, NULL, thread_tid, NULL); if (res_pthread_create != 0) { perror("pthread_create"); exit(EXIT_FAILURE); }
int res_pthread_detach = pthread_detach(tid); if (res_pthread_detach != 0) { perror("pthread_detach"); exit(EXIT_FAILURE); }
printf("主线程等待子线程结束(但实际上不需要等待,因为线程已被分离)\n"); sleep(3); printf("主线程结束\n");
return 0; }
|
需要注意的是,pthread_detach 不会等待子线程结束,如果在后者执行完毕之前主 线程退出,则整个进程退出,子线程被强制终止。
2.3pthread_cancel测试例程
2.3.1 显示调用取消点函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| #include <pthread.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h>
void *thread_tid(void *argv) { printf("Thread tid:%lu, started\n", (unsigned long)pthread_self()); printf("working\n"); sleep(1); pthread_testcancel(); printf("取消之后\n"); return NULL; }
int main(int argc, char *argv[]) { pthread_t tid; int res_pthread_create = pthread_create(&tid, NULL, thread_tid, NULL); if (res_pthread_create != 0) { perror("pthread_create"); exit(EXIT_FAILURE); }
int res_pthread_cancel = pthread_cancel(tid); if (res_pthread_cancel != 0) { perror("pthread_cancel"); exit(EXIT_FAILURE); } void *res; pthread_join(tid,&res); if (res==PTHREAD_CANCELED){ printf("线程被取消\n"); }else{ printf("线程未被取消 exit code:%ld\n",(long)res); }
return 0; }
|
2.3.2 异步取消
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| #include <pthread.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h>
void *thread_tid(void *argv) { printf("Thread tid:%lu, started\n", (unsigned long)pthread_self()); pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,NULL); printf("working\n"); int i=0; while(1){ printf("%d\n",i++); } }
int main(int argc, char *argv[]) { pthread_t tid; int res_pthread_create = pthread_create(&tid, NULL, thread_tid, NULL); if (res_pthread_create != 0) { perror("pthread_create"); exit(EXIT_FAILURE); }
int res_pthread_cancel = pthread_cancel(tid); if (res_pthread_cancel != 0) { perror("pthread_cancel"); exit(EXIT_FAILURE); } void *res; pthread_join(tid,&res); if (res==PTHREAD_CANCELED){ printf("线程被取消\n"); }else{ printf("线程未被取消 exit code:%ld\n",(long)res); }
return 0; }
|
2.3.3禁用取消
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| #include <pthread.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h>
void *thread_tid(void *argv) { printf("Thread tid:%lu, started\n", (unsigned long)pthread_self()); pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,NULL); pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,NULL); printf("working\n"); sleep(2); printf("after sleep\n"); return NULL; }
int main(int argc, char *argv[]) { pthread_t tid; int res_pthread_create = pthread_create(&tid, NULL, thread_tid, NULL); if (res_pthread_create != 0) { perror("pthread_create"); exit(EXIT_FAILURE); }
int res_pthread_cancel = pthread_cancel(tid); if (res_pthread_cancel != 0) { perror("pthread_cancel"); exit(EXIT_FAILURE); } void *res; pthread_join(tid,&res); if (res==PTHREAD_CANCELED){ printf("线程被取消\n"); }else{ printf("线程未被取消 exit code:%ld\n",(long)res); }
return 0; }
|