免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 58523 | 回复: 60
打印 上一主题 下一主题

[Linux] Linux系统开发那点事儿 分享经验得牛人力作!(获奖名单已公布-2014-5-28) [复制链接]

论坛徽章:
1
天蝎座
日期:2013-12-06 18:23:58
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2014-04-08 20:24 |只看该作者 |倒序浏览
获奖名单已公布,详情请看:http://bbs.chinaunix.net/thread-4140163-1-1.html

话题背景

Linux系统编程想必大家都已不陌生,高手众多,不过有些坎,即使高手也难逃一劫,前仆后继的被绊一跤。“系统编程”是指编写系统软件,其代码在底层运行,直接跟内核和核心系统库对话。比如说Linux系统调用和底层函数说明,如C库定义的函数。作为基础,系统程序员需要对Linux文件系统、I/O、缓存、进程、内存都有了解,要想成为大家则需精通。大家可以聊聊自己在开发过程中遇见的各种诡异的情景,奇葩的错误,比如api的使用死角,例如syslog传入的数据没有对%进行转义,内存爆栈,网络洪水,自己把自己DDOS打死;等等各种印象深刻的事情。

今日话题:

        1. 系统开发中遇见的那些头疼的问题
        2. 系统开发过程中的收获
        3. 如何做好Linux 系统开发


活动时间:

2014-4-8至2014-5-15

活动奖励:

我们将会选择几位突出的网友赠送一本常读常新的书籍《Linux系统编程》第二版,作者是大名鼎鼎Robert Love
这个作者可是非常有名,Google的高级工程师,写的书质量极高,书虽然不厚,内容却都是干货
Linux系统编程经典之作,根据Linux内核3.0更新 !
Linux程序设计方面的传奇人物Robert Love力作 !

奖品简介:
Linux系统编程(第2版)

作者: (美)Robert Love   
译者: 祝洪凯 李妹芳 付途
出版社:人民邮电出版社
ISBN:9787115346353
上架时间:2014-4-18
出版日期:2014 年4月
开本:16开
页码:420

图书样张:
g前言.DOC (5.47 MB, 下载次数: 70)
f序.DOC (28.5 KB, 下载次数: 42)
d译者序.DOC (29.5 KB, 下载次数: 43)
h目录.DOC (82 KB, 下载次数: 71)


01入门和概念.zip (1.7 MB, 下载次数: 169)
01入门和概念.z01 (5 MB, 下载次数: 149)
(样张文件需要两个都要下载解压才能打开)






论坛徽章:
208
巨蟹座
日期:2013-09-02 09:16:36卯兔
日期:2013-09-02 20:53:59酉鸡
日期:2013-09-05 21:21:45戌狗
日期:2013-10-15 20:51:17寅虎
日期:2013-10-18 21:13:16白羊座
日期:2013-10-23 21:15:19午马
日期:2013-10-25 21:22:48技术图书徽章
日期:2013-11-01 09:11:32双鱼座
日期:2013-11-01 20:29:44丑牛
日期:2013-11-01 20:40:00卯兔
日期:2013-11-11 09:21:32酉鸡
日期:2013-12-04 19:56:39
2 [报告]
发表于 2014-04-09 09:35 |只看该作者
问题倒多,可惜大部分是自己的问题

论坛徽章:
0
3 [报告]
发表于 2014-04-09 10:13 |只看该作者
我遇到的这个问题其实应该不算个问题,但在我刚开始学多线程编程的时候却困扰了我很久,在网上也没找到答案,或者说没有直接的答案,后来是自己去读了部分nptl源代码后才明白原因,虽然费时很多,但也收获良多。
问题很简单,就是关于线程取消的操作,在某种情况下,线程不管怎样都不能退出,问题肯定是出在锁上,但始终找不到死锁的地方,先帖段代码:
  1. #include <stdio.h>
  2. #include <unistd.h>
  3. #include <pthread.h>

  4. pthread_mutex_t lock;
  5. pthread_cond_t cond;
  6. void thrd_cleanup()
  7. {
  8.         printf("thread canceled\n");

  9.         pthread_mutex_unlock(&lock);
  10. }

  11. void thrd_func()
  12. {
  13.         pthread_cleanup_push(thrd_cleanup, NULL);
  14.         printf("thread: enter\n");
  15.         pthread_mutex_lock(&lock);
  16.         pthread_cond_wait(&cond, &lock);
  17.         pthread_mutex_unlock(&lock);
  18.         pthread_cleanup_pop(0);
  19.         printf("thread: exit\n");
  20. }

  21. int main(int argc, char *argv[])
  22. {
  23.         pthread_t tid[4];

  24.         pthread_mutex_init(&lock, NULL);
  25.         pthread_cond_init(&cond, NULL);

  26.         for (int i = 0; i < 4; ++i) {
  27.                 int ret = pthread_create(&tid[i], NULL, thrd_func, NULL);
  28.                 if (ret) {
  29.                         perror("pthread_create");
  30.                 }
  31.         }

  32.         sleep(3);

  33.         pthread_mutex_lock(&lock);

  34.         for (int i = 0; i < 4; ++i) {
  35.                 printf("before cancel\n");
  36.                 pthread_cancel(tid[i]);
  37.                 pthread_join(tid[i], NULL);
  38.                 printf("after cancel\n");
  39.         }

  40.         pthread_mutex_unlock(&lock);

  41.         sleep(6);

  42.         return 0;
  43. }
复制代码
上面代码得到的输出为
  1. thread: enter
  2. thread: enter
  3. thread: enter
  4. thread: enter
  5. before cancel
复制代码
可见在第一个线程退出的时候出了问题,一开始就几乎可以肯定是锁这出了问题,可一直找不到原因,attach该进程,得到的结果为
  1. (gdb) bt
  2. #0  0xb772f424 in __kernel_vsyscall ()
  3. #1  0xb7707e1c in pthread_join () from /lib/i386-linux-gnu/libpthread.so.0
  4. #2  0x080489f4 in main (argc=1, argv=0xbfe68a24) at main.c:67
复制代码
可见,程序在调用pthread_join后阻塞了,再查看当前进程中的线程:
  1. (gdb) info threads
  2.   Id   Target Id         Frame
  3.   4    Thread 0xb6d52b40 (LWP 5658) "foo" 0xb772f424 in __kernel_vsyscall ()
  4.   3    Thread 0xb6551b40 (LWP 5659) "foo" 0xb772f424 in __kernel_vsyscall ()
  5.   2    Thread 0xb5d50b40 (LWP 5660) "foo" 0xb772f424 in __kernel_vsyscall ()
  6. * 1    Thread 0xb75546c0 (LWP 5656) "foo" 0xb772f424 in __kernel_vsyscall ()
复制代码
显示已经有一个线程成功退出,而查看进程的/proc文件系统信息得到的却是:
  1. $ls /proc/5656/task
  2. 5656  5657  5658  5659  5660
复制代码
这却说明刚才的那个线程没有完全退出,当时我觉得这是相当诡异的,所谓百思不得其解啊,最后经过分析nptl关于pthread_cancel操作的源码后,终于找到了原因:

我们在进入线程的时候注册了线程清理理函数,随后进入等待状态,注意这时候主线程已经持有锁了,并调用pthread_cancel和pthread_join,这个时候nptl的实现中需要再次持有该锁,这时候问题就出现了,主线程持有锁并等待pthread_join的结束,而nptl库需要先拿到锁才能返回,这就永远不会结束,导致上面的问题。

经过这个问题之后,觉得多线程编程真是个头疼的问题,稍有不甚就会出现各种诡异的问题,尤其对于初学者,经验不足,解决起这些问题是费时费力又不一定有效果。

评分

参与人数 1可用积分 +2 收起 理由
crazyhadoop + 2 有锁的情形下就要考虑到各种情形了,稍不留.

查看全部评分

论坛徽章:
17
戌狗
日期:2013-09-02 23:43:02技术图书徽章
日期:2014-04-29 14:16:02技术图书徽章
日期:2014-04-24 15:51:26未羊
日期:2014-04-06 22:10:30丑牛
日期:2014-04-06 21:23:29辰龙
日期:2014-04-06 21:20:22处女座
日期:2014-04-06 21:16:18技术图书徽章
日期:2014-04-02 15:10:51金牛座
日期:2014-03-10 22:26:18巨蟹座
日期:2014-02-17 17:12:12技术图书徽章
日期:2014-01-24 10:38:43摩羯座
日期:2013-11-29 18:00:18
4 [报告]
发表于 2014-04-09 10:55 |只看该作者
支持活动,好活动探讨linux开源系统。

论坛徽章:
0
5 [报告]
发表于 2014-04-09 10:59 |只看该作者
1. 系统开发中遇见的那些头疼的问题
   多线程, 用pthread的时候, 栈开小了, 出了错是panic 吧.
   tcp/ip 数据同步出问题, x86到power时, 映射数据会有大小端转换

2. 系统开发过程中的收获
   解决方案没把握时, 一定要写个demo来验证一下.

论坛徽章:
0
6 [报告]
发表于 2014-04-09 13:37 |只看该作者
最大的坑就是那个著名的 a.out,一定要./a.out才可以执行。有多少初学者, gcc hello.c一次写对编译成功并执行成功的?

论坛徽章:
324
射手座
日期:2013-08-23 12:04:38射手座
日期:2013-08-23 16:18:12未羊
日期:2013-08-30 14:33:15水瓶座
日期:2013-09-02 16:44:31摩羯座
日期:2013-09-25 09:33:52双子座
日期:2013-09-26 12:21:10金牛座
日期:2013-10-14 09:08:49申猴
日期:2013-10-16 13:09:43子鼠
日期:2013-10-17 23:23:19射手座
日期:2013-10-18 13:00:27金牛座
日期:2013-10-18 15:47:57午马
日期:2013-10-18 21:43:38
7 [报告]
发表于 2014-04-09 13:47 |只看该作者
mmap失败返回的不是想当然的NULL,而是MAP_FAILED(-1)

论坛徽章:
11
技术图书徽章
日期:2014-03-01 14:44:34天蝎座
日期:2014-05-21 22:11:59金牛座
日期:2014-05-30 17:06:14
8 [报告]
发表于 2014-04-09 14:27 |只看该作者
回复 3# 阿注哥
分析NPTL源码解决问题,很强大啊!
个人使用多线程时恪守两个原则:
1. “thread is evil”,能不用就不用。Linux/UNIX下,多线程比多进程的优势并没有教科书理论阐释的那么美好,不过多线程确实可以简化共享数据结构的实现,看看多进程五花八门的IPC就知道了。
2. 使用简单的核心API,少用高大上。理解mutex/condition variable/semaphore API就可以解决多数问题,当想用push/pop/cancel等等偏门API时,反省自己的代码架构,通常可以避免之。

   

论坛徽章:
0
9 [报告]
发表于 2014-04-09 14:49 |只看该作者
回复 8# timespace


    linux的线程用轻量进程实现,实则区别不大,记得看过一篇文章,详细介绍其区别,也说了没特别的必要性就尽量避免!那么花了我好多时间才搞明白,算是印象深刻的一次经历了。

论坛徽章:
0
10 [报告]
发表于 2014-04-10 09:15 |只看该作者
做C语言开发有一段时间了,我的一些经验分享给大家:

1 C就是C,不要在C中实现try ... catch, 如果实在避不开,用一下setjmp longjunp,不建议大量使用,多用if做判断更好

2 C就是C,不要在C中试图实现类似C++/Java等语言中的类,C吗?简单点更好

3 内存管理,如果不能简单到每次申请大小都是固定长度字节的内存,那就别自己管理内存了,有更好的工具可以使用,比如:Google Performance Tools
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP