GDB调试带参数程序

97 篇文章 1 订阅

[cpp]  view plain copy
  1. #include <stdio.h>  
  2. #include <pthread.h>  
  3. #include <sched.h>  
  4. #include <errno.h>  /*ESRCH*/  
  5.   
  6. #define MINI_STACK_SIZE (0x20000)  
  7. #define MINI_PRIORITY   (66)  
  8.   
  9. #define RET_OK  (0)  
  10. #define RET_ERR (-1)  
  11.   
  12. /*线程管理结构 -- ID与名字映射,方便从名字找到对应线程*/  
  13. #define THREAD_NAME_LEN (10)  
  14. typedef struct  
  15. {  
  16.     char        thread_name[THREAD_NAME_LEN];  
  17.     pthread_t   thread_id;  
  18. }THREAD_MGR_s;  
  19.   
  20. typedef void (*THREAD_FUNC)(void *param);  
  21.   
  22. /********************************************************************************** 
  23.                         局部函数声明 
  24.  **********************************************************************************/  
  25. int add_thread(const char *name, const pthread_t id);  
  26. int thread_alive(const pthread_t thread_id);  
  27. int thread_destroy(pthread_t thread_id);  
  28.   
  29. /********************************************************************************** 
  30.                         局部函数定义 
  31.  *********************************************************************************/  
  32.   
  33. /* 
  34.  *创建线程, 
  35.  *成功返回 > 0 值 
  36.  *线程属性主要设置: 
  37.         - 调度策略, 
  38.         - 是否绑定, 
  39.         - 是否分离, 
  40.         - 堆栈大小, 
  41.         - 线程优先级 
  42.  */  
  43. pthread_t thread_create(int stack_size, int priority, int detach, THREAD_FUNC func, const char *name)  
  44. {  
  45.     pthread_t           thread_id;  
  46.     pthread_attr_t      attr;  
  47.     struct sched_param  schedparam;  
  48.     int                 ret;  
  49.   
  50.     /*线程初始化        -- 0为成功*/  
  51.     ret = pthread_attr_init(&attr);  
  52.   
  53.     /*  设置调度策略    -- 0为成功 
  54.         SCHED_OTHER 默认 
  55.         SCHED_FIFO  先进先出 
  56.         SCHED_RR    轮转 
  57.      */  
  58.     ret |= pthread_attr_setschedpolicy(&attr, SCHED_RR);  
  59.   
  60.     /*  设置线程绑定状态    -- 0为成功 
  61.         绑定    PTHREAD_SCOPE_SYSTEM    默认 -- 高效线程切换方式 
  62.         非绑定  PTHREAD_SCOPE_PROCESS   无法设置 
  63.  
  64.         线程的调度是面向轻量级线程的,非绑定时,一个轻量线线程对应用户态下 
  65.         多个线程;绑定状态下,一个用户线程绑定于一个轻量级线程,CPU切换线程 
  66.         时无需寻找空闲轻量级线程绑定,直接切换,相对于非绑定线程,切换时间减 
  67.         少 
  68.      */  
  69.   
  70.      ret |= pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);  
  71.   
  72.      /*设置线程是否分离 -- 0为成功 
  73.  
  74.         分离线程    PTHREAD_CREATE_DETACHED 
  75.             - 如果创建分离线程 (PTHREAD_CREATE_DETACHED),则该线程一退出,便可重用 
  76.             - 其线程 ID 和其他资源。 
  77.  
  78.         非分离线程  PTHREAD_CREATE_JOINABLE 
  79.             - 非分离线程在终止后,必须要有一个线程用 join 来等待它。否则,不会释放 
  80.             - 该线程的资源以供新线程使用,而这通常会导致内存泄漏。因此,如果不希望 
  81.             - 线程被等待,请将该线程作为分离线程来创建。 
  82.             - 需要调用pthread_join(pthread_t thread_id, (void *)ret);等待后线程退出 
  83.               后的线程ID和其他资源才被释放(如:fork -- wait 相同) 
  84.  
  85.       */  
  86. #if 1  
  87.     if (0 != detach)  
  88.     {  
  89.         ret |= pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);  
  90.     }  
  91.     else  
  92.     {  
  93.         ret |= pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);    
  94.     }  
  95. #endif  
  96.     if (MINI_STACK_SIZE > stack_size) {  
  97.         stack_size = MINI_STACK_SIZE;  
  98.     }  
  99.   
  100.     /*设置线程堆栈大小  --  0为成功*/  
  101.     ret |= pthread_attr_setstacksize(&attr, stack_size);  
  102.   
  103.     /*设置线程优先级    --  0为成功*/  
  104.     schedparam.__sched_priority = priority + MINI_PRIORITY;  
  105.     ret |= pthread_attr_setschedparam(&attr, &schedparam);  
  106.   
  107.     if (0 != ret)  
  108.     {  
  109.         printf("0 != ret\n");  
  110.         goto LAB_ERR;  
  111.     }  
  112.   
  113.     /*线程创建*/  
  114.     ret = pthread_create(&thread_id, &attr, (void *)func, NULL);  
  115.       
  116.     if (0 != ret)  
  117.     {  
  118.         printf("pthread_create error\n");  
  119.         goto LAB_ERR;  
  120.     }  
  121.   
  122. #if 0  
  123.     if (0 != detach)  
  124.     {  
  125.         /*调用者调用pthread_join(pthread_id)后,如果该线程没有运行结束,调用者会被阻塞*/  
  126.         ret |= pthread_detach(thread_id);  
  127.     }  
  128. #endif      
  129.   
  130.     ret |= add_thread(name, thread_id);  
  131.     if (0 != ret)  
  132.     {  
  133.         thread_destroy(thread_id);  
  134.         goto LAB_ERR;  
  135.     }  
  136.   
  137.     printf("thread create ok, id = [%lu]\n", (unsigned long int)thread_id);  
  138. LAB_OK:      
  139.     return (thread_id);  
  140. LAB_ERR:  
  141.     return (RET_ERR);  
  142. }  
  143.   
  144.   
  145. /*查看线程是否还存在*/  
  146. int thread_alive(const pthread_t thread_id)  
  147. {  
  148.     int ret;  
  149.   
  150.     ret = pthread_kill(thread_id, 0);  
  151.     if (ESRCH == ret)  
  152.     {  
  153.         printf("thread(%lu) not exit\n", thread_id);  
  154.         goto LAB_ERR;  
  155.     }  
  156.     else if (EINVAL == ret)  
  157.     {  
  158.         printf("signal not legal\n");  
  159.         goto LAB_ERR;  
  160.     }  
  161.     else  
  162.     {  
  163.         printf("thread alive\n");  
  164.     }  
  165.   
  166.     return (RET_OK);  
  167. LAB_ERR:  
  168.     return (RET_ERR);  
  169. }  
  170.   
  171. int thread_destroy(pthread_t thread_id)  
  172. {  
  173.     int ret;  
  174.     /* 
  175.           注意: 
  176.           pthread_kill是向一个线程发送signal信号,如果线程不存在或不安装signal处理handle, 
  177.           那这个signal将会转向进程进行处理,如果发送pthread_kill(thread_id, SIGKILL),线程 
  178.           也没有安装signal处理handle,那么整个程序就会退出.发送pthread_kill(thread_id, 0), 
  179.           signal = 0为保留值,只是用于测试线程是否退出. 
  180.           0:成功 
  181.           ESRCH:不存在或退出 
  182.           EINVAL:信号不合法 
  183.      */  
  184.   
  185.     if (RET_OK == thread_alive(thread_id))  
  186.     {  
  187.         /*线程还在运行之中*/  
  188.         printf("thread(%lu) is alive\n", thread_id);  
  189.         /*终止线程运行,pthread_cancel函数的功能是给线程发送取消信号,使线程从取消点退出. 
  190.           0:成功,成功并不代表thread会终止   
  191.          */  
  192.         ret = pthread_cancel(thread_id);  
  193.         if (0 == ret)  
  194.         {  
  195.             printf("send thread cancel ok\n");  
  196.   
  197.         }  
  198.         else  
  199.         {  
  200.             printf("send thread cancel error\n");  
  201.             goto LAB_ERR;  
  202.         }  
  203.     }  
  204.   
  205.     printf("thread destroy ok\n");  
  206.     return RET_OK;  
  207. LAB_ERR:  
  208.     return RET_ERR;  
  209. }  
  210.   
  211. /*线程执行函数*/  
  212. static void thread_func(void *param)  
  213. {  
  214.     int sleep_tm_count = 0;  
  215.     printf("start func now!\n");  
  216.   
  217.     while (10 >= sleep_tm_count++)  
  218.     {  
  219.         sleep(1);  
  220.     }  
  221.   
  222.     printf("thread fun exit\n");  
  223. }  
  224.   
  225. int main(int argc, char *argv[])  
  226. {  
  227.     const char      thread_name[] = "one";  
  228.     pthread_t       thread_id;  
  229.   
  230.     unsigned char   detach_flag = 0;  
  231.   
  232.     detach_flag = 1;  
  233.   
  234.     if (2 == argc) {  
  235.         detach_flag = atoi(argv[0]);  
  236.     }  
  237.       
  238.     thread_id = thread_create(0x20000, 10, detach_flag, (THREAD_FUNC)thread_func, thread_name);  
  239.     if (RET_ERR == thread_id)  
  240.     {  
  241.         printf("thread create error\n");  
  242.     }  
  243.     else  
  244.     {  
  245.         printf("pthread join now\n");  
  246.         pthread_join(thread_id, NULL);  
  247.         printf("pthread join out\n");  
  248.     }  
  249.   
  250. #if 0  
  251.     printf("go to sleep now\n");  
  252.     sleep(-1);  
  253. #else  
  254.     printf("exit process now\n");  
  255. #endif  
  256.     return 0;  
  257. }  
  258.   
  259.   
  260. /***************************** 线程管理函数 start********************************** 
  261.  *设计思想: 
  262.  
  263.  
  264.  ****************************** 线程管理函数 end **********************************/  
  265.   
  266. /*添加新线程到线程管理结构*/  
  267.  int add_thread(const char *name, const pthread_t id)  
  268.  {  
  269.   
  270.     return (RET_OK);  
  271. LAB_ERR:      
  272.     return (RET_ERR);  
  273.  }  

gcc ./test.c -lpthread -g -o test.elf

root@ubuntu:/home/libz/share/project/gdb-test# gdb ./test.elf -q

Reading symbols from /home/libz/share/project/gdb-test/test.elf...done.
(gdb) set args 0
(gdb) r

Starting program: /home/libz/share/project/gdb-test/test.elf 0
[Thread debugging using libthread_db enabled]
[New Thread 0xb7feab70 (LWP 5174)]
thread create ok, id = [3086920560]
pthread join now
start func now!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值