python下使用ctypes获取threading线程id

python的多线程坑坑不断… …

python的threading因为封装的太好, 很多本源的东西在threading对象里是拿不到的.  首先需要说明的是python threading的name跟ident,这些看起来是线程名字,线程id其实只是个标识,注意是标识而已.  简单过了下threading创建对象及启动线程的代码,发现ident跟pstree查到的线程id是两码事. 

该文章写的有些乱,欢迎来喷 ! 另外文章后续不断更新中,请到原文地址查看更新http://xiaorui.cc/?p=3017

我在 stackoverflow 查询到了一些关于pyhton线程id的获取方式,但大多数人其实对线程id是不关心的,他们会利用threading给予的threading.currentThread().ident threading.currentThread().name来识别线程.  最后在查到一老外写的使用ctypes调用系统的动态链接库libc.so.6 来获取线程id的方法, 当然事实证明是有效果的. 


老外的连接 http://blog.devork.be/2010/09/finding-linux-thread-id-from-within.html

ctypes是Python的一个外部库,提供和C语言兼容的数据类型,可以很方便地调用C DLL中的函数. 我对这个ctypes理解也不深入,在以前的项目中用过,表示有些粗暴.

废话不多说, 直接上python ctypes样例,关于这186,224,178不知道啥意思.

import ctypes
for id in [186, 224, 178]:
    tid = ctypes.CDLL('libc.so.6').syscall(id)  #syscall系统调用


下面是python threading获取线程id的实例代码:

#xiaorui.cc

#coding:utf-8
import os
import threading
import ctypes
import time
import requests

def pthread_level1(i):
    print "workor id :%s"%i
    #获取threading对象的标识ident
    print threading.currentThread()
    print threading.currentThread().ident
    print "threaing id: ",ctypes.CDLL('libc.so.6').syscall(186)
    d = requests.get("http://www.google.com")
    time.sleep(100)
    return


if __name__ == "__main__":
    l = []
    for i in xrange(5):
        t = threading.Thread(target=pthread_level1,args=(i,))
        l.append(t)
    for i in l:
        i.start()
    #查看进程跟线程的关系
    os.system("pstree -p " + str(os.getpid()))
    for i in l:
        i.join()

    print "Sub-process done."


这是上面py代码运行后的结果,  跟我们预期的效果一致.

[ruifengyun@wx-test-social11:~]$python a.py
workor id :0
<Thread(Thread-1, started 140665607177984)>
 workor id :1
140665607177984<Thread(Thread-2, started 140665596688128)>

140665596688128workor id :2

threaing id:  24828
<Thread(Thread-3, started 140665586198272)>
140665586198272
threaing id:  24829
threaing id:  workor id :3
<Thread(Thread-4, started 140665575708416)>
140665575708416
threaing id:  24830
24827
workor id :4
<Thread(Thread-5, started 140665565218560)>
140665565218560
threaing id:  24831
python(24826)─┬─pstree(24832)
              ├─{python}(24827)
              ├─{python}(24828)
              ├─{python}(24829)
              ├─{python}(24830)
              └─{python}(24831)


可以另起一个终端使用pstree -p pid看看是否正确.  

[ruifengyun@wx-test-social11:~]$pstree -p 24826
python(24826)─┬─{python}(24827)
              ├─{python}(24828)
              ├─{python}(24829)
              ├─{python}(24830)
              └─{python}(24831)


那么我们费尽心思取到python的线程id是为了什么?  strace -p pid/线程 的状态.  可以看到24831线程正在建立google.com的连接, 很明显这连接被拒了.

[ruifengyun@wx-test-social11:~]strace -p 24826
Process 24826 attached - interrupt to quit
futex(0x1abfcd0, FUTEX_WAIT_PRIVATE, 0, NULL
^C <unfinished ...>
Process 24826 detached

[ruifengyun@wx-test-social11:~]strace -p 24828
Process 24828 attached - interrupt to quit
connect(8, {sa_family=AF_INET, sin_port=htons(80), sin_addr=inet_addr
("216.58.221.228")}, 16 


END.  下次有时间在专门瞅瞅python ctypes的用法. 


大家觉得文章对你有些作用! 如果想赏钱,可以用微信扫描下面的二维码,感谢!
另外再次标注博客原地址  xiaorui.cc

2 Responses

  1. gd 2016年3月22日 / 上午9:35

    还能这么干! 学习了!

  2. linuxy 2016年3月21日 / 下午6:44

    妈蛋 还有广告!

发表评论

邮箱地址不会被公开。 必填项已用*标注