背景
开工前我就觉得有什么不太对劲,感觉要背锅。这可不,上班第三天就捅锅了。
我们有个了不起的后台程序,可以动态加载模块,并以线程方式运行,通过这种形式实现插件的功能。而模块更新时候,后台程序自身不会退出,只会将模块对应的线程关闭、更新代码再启动,6 得不行。
于是乎我就写了个模块准备大展身手,结果忘记写退出函数了,导致每次更新模块都新创建一个线程,除非重启那个程序,否则那些线程就一直苟活着。
这可不行啊,得想个办法清理呀,要不然怕是要炸了。
那么怎么清理呢?我能想到的就是两步走:
找出需要清理的线程号 tid; 销毁它们;找出线程ID
和平时的故障排查相似,先通过 ps 命令看看目标进程的线程情况,因为已经是 setName 设置过线程名,所以正常来说应该是看到对应的线程的。 直接用下面代码来模拟这个线程:
Python 版本的多线程
#coding: utf8import threadingimport osimport timedef tt(): info = threading.currentThread() while True: print 'pid: ', os.getpid() print info.name, info.ident time.sleep(3)t1 = threading.Thread(target=tt)t1.setName('OOOOOPPPPP')t1.setDaemon(True)t1.start()t2 = threading.Thread(target=tt)t2.setName('EEEEEEEEE')t2.setDaemon(True)t2.start()t1.join()t2.join()
输出:
root@10-46-33-56:~# python t.py
pid: 5613
OOOOOPPPPP 139693508122368
pid: 5613
EEEEEEEEE 139693497632512
...
可以看到在 Python 里面输出的线程名就是我们设置的那样,然而 Ps 的结果却是令我怀疑人生:
root@10-46-33-56:~# ps -Tp 5613
PID SPID TTY TIME CMD
5613 5613 pts/2 00:00:00 python
5613 5614 pts/2 00:00:00 python
5613 5615 pts/2 00:00:00 python
正常来说不该是这样呀,我有点迷了,难道我一直都是记错了?用别的语言版本的多线程来测试下:
C 版本的多线程
#include<stdio.h>#include<sys/syscall.h>#include<sys/prctl.h>#include<pthread.h>void *test(void *name){ pid_t pid, tid; pid = getpid(); tid = syscall(__NR_gettid); char *tname = (char *)name; // 设置线程名字 prctl(PR_SET_NAME, tname); while(1) { printf("pid: %d, thread_id: %u, t_name: %s/n", pid, tid, tname); sleep(3); }}int main(){ pthread_t t1, t2; void *ret; pthread_create(&t1, NULL, test, (void *)"Love_test_1"); pthread_create(&t2, NULL, test, (void *)"Love_test_2"); pthread_join(t1, &ret); pthread_join(t2, &ret);}
输出:
root@10-46-33-56:~# gcc t.c -lpthread && ./a.out
pid: 5575, thread_id: 5577, t_name: Love_test_2
pid: 5575, thread_id: 5576, t_name: Love_test_1
新闻热点
疑难解答