摘要:在使用多线程程序时,有时会遇到程序功能异常的情况,而这种异常情况并不是每次都发生,很难模拟出来。这时就需要运用在程序运行时跟踪线程的手段,而linux系统的LWP和strace命令正是这种技术手段。本文对LWP和strace命令做了简明扼要的介绍,并通过一个实例来说明如何运用。总而言之,LWP和strace的使用可以提高多线程程序的可维护性。

问题描述:

我们来看一个问题:程序tcp_client同时创建多个线程向同一个服务器发送数据,每个线程发送不同类型的数据,服务器接收数据后,可以通过界面查看到多个数据在刷新。程序运行一段时间后,突然出现只有某个类型的数据不刷新,其他数据刷新正常,但是服务端和客户端程序都没有报错。这时我们该怎么办?

很明显,这时程序调试者需要知道不刷新线程的线程ID,然后通过某种手段查看该线程为何出现了异常。通过linux的ps -eLF|grep pid命令可以查看进程的线程ID(LWP号),但是问题在于如果我们没有在创建线程时记录其线程ID,我们仍然无法得知哪个LWP号是我们想要追踪的。

我们来看一下LWP号是什么,以及如何在创建线程时记录每个线程的LWP号。

pthread_create是基于clone实现的, 创建出来的其实是进程, 但这些进程与父进程共享很多东西,

共享的东西都不用复制给子进程, 从而节省很多开销, 因此,这些子进程也叫轻量级进程(light-weight process)简称LWP. 每个LWP都会与一个内核线程绑定, 这样它就可以作为独立的调度实体参与cpu竞争.

LWP被pthread封装后, 以线程面目示人, 它有自己的id, 这里要区分 phtread_create

给LWP分配的id, 和操作系统给LWP分配的进程id. 这两者是不同的, 前者用于标志线程,可以暴露给

用户, 后者其实就是进程的id, 它没有暴露出来, 必须通过系统调用来得到.

获取LWP的方法是通过syscall系统调用(具体说明参加man手册),下面是一个例子程序:#include

#include

#include

#include

//线程处理函数,输出LWP号

void *func(void *argv)

{

//获取LWP的方法1

int lwp;

lwp = syscall(__NR_gettid);

printf("lwp[%d]\n", lwp);

//获取LWP的方法2

int lwp2;

lwp2 = syscall(SYS_gettid);

printf("lwp2[%d]\n", lwp2);

sleep(50);

}

int main(void)

{

pthread_t thd;

pthread_create(&thd, NULL, func, NULL); //创建线程

sleep(60);

return 0;

}

在获取LWP号以后,接下来就是通过strace命令对线程进行追踪了。

strace常用来跟踪进程执行时的系统调用和所接收的信号。 在Linux世界,进程不能直接访问硬件设备,当进程需要访问硬件设备(比如读取磁盘文件,接收网络数据等等)时,必须由用户态模式切换至内核态模式,通 过系统调用访问硬件设备。strace可以跟踪到一个进程产生的系统调用,包括参数,返回值,执行消耗的时间。

在理想世界里,每当一个程序不能正常执行一个功能时,它就会给出一个有用的错误提示,告诉你在足够的改正错误的线索。但遗憾的是,我们不是生活在理想世界 里,起码不总是生活在理想世界里。有时候一个程序出现了问题,你无法找到原因。这就是调试程序出现的原因。strace是一个必不可少的 调试工具,strace用来监视系统调用。你不仅可以调试一个新开始的程序,也可以调试一个已经在运行的程序(把strace绑定到一个已有的PID上 面)。

strace的参数有很多,常见的参数介绍如下:

-o filename  将strace的输出写入文件filename

-p pid      跟踪指定的进程pid.

-t   在输出中的每一行前加上时间信息.

-tt  在输出中的每一行前加上时间信息,微秒级.

-T   显示每一调用所耗的时间.

-f   跟踪由fork调用所产生的子进程.

-ff  如果提供-o filename,则所有进程的跟踪结果输出到相应的filename.pid中,pid是各进程的进程     号.

举个例子:我们对tcp_client程序做一个小小的改动,在通过pthread_create创建线程后,每个线程里都通过syscall函数记录其LWP号,同时记录该LWP号对应的数据类型。如果程序再次出现文章开头时提到的异常状况,这时我们可以通过“strace -o tcp_client.txt -tt -p 欲追踪的LWP号”,这样就很快就能知道发生异常的线程在做哪些系统调用了。

总结:在设计程序的时候,一定要考虑将来的维护问题。对于多线程程序,其调试会更加困难,通过在创建线程中记录LWP号和对应的线程功能,可以为以后的调试提供很大帮助。

参考文章:

1、关于Linux的进程和线程

2、linux strace命令:

linux跟踪线程,linux跟踪线程的方法:LWP和strace命令相关推荐

  1. linux跟踪线程的方法:LWP和strace命令

    摘要:在使用多线程程序时,有时会遇到程序功能异常的情况,而这种异常情况并不是每次都发生,很难模拟出来.这时就需要运用在程序运行时跟踪线程的手段,而linux系统的LWP和strace命令正是这种技术手 ...

  2. linux 跟踪命令执行过程,Linux的strace命令跟踪线程死锁

    strace命令,是Linux提供的跟踪系统调用的命令,需要sudo或root权限,可以查看进程(线程)使用的系统调用. 基本用法:sudo strace -p 进程号 如果一个线程递归获取同一个锁, ...

  3. linux 线程--内核线程、用户线程实现方法

    Linux上进程分3种,内核线程(或者叫核心进程).用户进程.用户线程 内核线程拥有 进程描述符.PID.进程正文段.核心堆栈 当和用户进程拥有相同的static_prio 时,内核线程有机会得到更多 ...

  4. linux:线程同步的5种方法

    linux:线程同步的5种方法 一.为什么要使用线程: 二.线程同步的5种方法 2.1 互斥量 2.2 读写锁 2.3 条件变量 2.4 自旋锁 2.5 屏障 一.为什么要使用线程: <1> ...

  5. Linux设备驱动程序中创建线程的方法

    参考博客文章来源:https://blog.csdn.net/ezimu/article/details/60467017 第一种方法:kernel_thread #include <linux ...

  6. linux c 线程同步的三种方法

    目录 一.互斥锁(mutex) 二.条件变量(cond) 三.信号量(sem) 线程的最大特点是资源的共享性,但资源共享中的同步问题是多线程编程的难点.linux下提供了多种方式来处理线程同步,最常用 ...

  7. Linux 线程同步的三种方法

    程的最大特点是资源的共享性,但资源共享中的同步问题是多线程编程的难点.linux下提供了多种方式来处理线程同步,最常用的是互斥锁.条件变量和信号量. 一.互斥锁(mutex) 通过锁机制实现线程间的同 ...

  8. Linux C线程同步的三种方法

    void* thr_fn1() {printf ("111111"); }int main() {int err;pthread_t tid;void *tret;err = pt ...

  9. Linux c 线程分离(两种方法实现线程分离)

    文章目录 1.使用函数实现线程分离 2.通过属性实现线程分离 3.杀死线程函数 1.使用函数实现线程分离 // 创建线程 int pthread_create(pthread_t &tid,c ...

  10. Linux下查看进程和线程

    在linux中查看线程数的三种方法 1.top -H 手册中说:-H : Threads toggle 加上这个选项启动top,top一行显示一个线程.否则,它一行显示一个进程. 2.ps xH 手册 ...

最新文章

  1. 带权重的随机输出数组中的元素
  2. 自定义MyHttpServletRequest解决过滤器拦截@RequestBody整体JSON请求问题
  3. golang中的strings.Trim
  4. Python里面对于嵌套列表的查询
  5. SAP在Kubernetes上打造的Kyma到底是个什么东东
  6. 高通android开源代码下载,高通平台Android源码bootloader分析之sbl1(三)
  7. 【十三】Jmeter:“CSV 数据文件设置”参数化请求中出现带有逗号的参数值
  8. 绝对干货:保险公司决策分析系统建设方案
  9. Android 快捷方式
  10. 使用 .Net Memory Profiler 诊断 .NET 应用内存泄漏(方法与实践)
  11. 在java中什么是所有类的父类_java中object是所有类的父类吗
  12. TensorFlow实现对花朵数据集的图片分类(保证运行成功)
  13. python简单的爬虫实例
  14. 【openwrt】初探 基于MT7621
  15. Java获取汉字对应的拼音(全拼或首字母)
  16. 命令行启动mysql闪退
  17. 考研英语前缀总结·十五
  18. R语言:方差分析,单因素方差分析,单个协变量的单因素方差分析,双因素方差分析,多元方差分析
  19. 火狐浏览器打印网页不全_打印网页显示不全,求助
  20. 12306Bypass-分流抢票 火车票抢票攻略

热门文章

  1. varchar,char,varchar2,mybatis查询无返回
  2. [BZOJ 3709] Bohater
  3. 峰Redis学习(7)Redis 之Keys 通用操作
  4. mysql的一些查询优化,count优化,limit优化
  5. c语言 int (*p)[5] 类型分析
  6. 输入身高、体重、性别,判断是否是标准体重,男性标准=(身高-100)+-3,女性标准=(身高-110)+-3...
  7. 刚创建了蕝薱嚣张IT部落
  8. HTML(Hepertext Markup Language 超文本标记语言)
  9. 美团在ACL2021上提出基于对比学习的文本表示模型,效果提升8%
  10. 【机器学习案例】酒店用机器学习,预测哪些客人会放鸽子