pthread_kill 實驗
Thread as Process
在 Linux 底下,每個 thread 在排程時都會被當作 process,也都有個 pid。所以在 kill thread 的 pid 時,會在該 thread 起 signal handler。
Code
#include <pthread.h>
#include <unistd.h>
#include <stdio.h>
#include <signal.h>
#include <sys/types.h>
thread_local int cnt = 0;
void catch_function(int signo) {
++cnt;
printf("%d cnt: %d\n", gettid(), cnt);
}
void* try_thread(void*) {
printf("try_thread: %d\n", gettid());
for (;;) {
sleep(1);
}
return 0;
}
int main() {
printf("main: %d\n", gettid());
signal(SIGINT, catch_function);
pthread_t t1;
pthread_t t2;
pthread_create(&t1, NULL, try_thread, NULL);
pthread_create(&t2, NULL, try_thread, NULL);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
puts("joined");
return 0;
}
Result
每個 thread (包括 main thread)都有自己的 cnt,所以送 signal 時,可以不同的 cnt 在增長。
$ g++ thread_kill.cpp -pthread
$ ./a.out &
[1] 1393371
main: 1393371
try_thread: 1393373
try_thread: 1393374
$ kill -s SIGINT 1393371
1393371 cnt: 1
$ kill -s SIGINT 1393371
1393371 cnt: 2
$ kill -s SIGINT 1393371
1393371 cnt: 3
$ kill -s SIGINT 1393373
1393373 cnt: 1
$ kill -s SIGINT 1393373
1393373 cnt: 2
$ kill -s SIGINT 1393373
1393373 cnt: 3
$ kill -s SIGINT 1393374
1393374 cnt: 1
$ kill -s SIGINT 1393374
1393374 cnt: 2
$ kill -s SIGINT 1393374
1393374 cnt: 3
pthread_kill
在 process 裡面對自己的 thread 送 signal。pthread_cancel 就是用這種方式做的。
Code
#include <pthread.h>
#include <unistd.h>
#include <stdio.h>
#include <signal.h>
#include <sys/types.h>
void catch_function(int signo) {
printf("%d signal: %d\n", gettid(), signo);
}
void* try_thread(void*) {
printf("try_thread: %d\n", gettid());
for (int i = 0; i < 3; ++i) {
printf("%d: %d\n", gettid(), i);
sleep(4);
}
return 0;
}
int main() {
signal(SIGINT, catch_function);
printf("main: %d\n", gettid());
pthread_t t1;
pthread_t t2;
pthread_create(&t1, NULL, try_thread, NULL);
pthread_create(&t2, NULL, try_thread, NULL);
sleep(1);
pthread_kill(t1, SIGINT);
sleep(1);
pthread_kill(t1, SIGINT);
sleep(1);
pthread_kill(t1, SIGINT);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
puts("joined");
return 0;
}
Result
sleep 會因為 SIGINT 中斷,所以 kill 3 次 t1 會讓 t1 優先結束。
main: 1451041
try_thread: 1451042
1451042: 0
try_thread: 1451043
1451043: 0
1451042 signal: 2
1451042: 1
1451042 signal: 2
1451042: 2
1451042 signal: 2
1451043: 1
1451043: 2
joined