免费注册 查看新帖 |

Chinaunix

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

[C] 求助:fgets 读文件死锁! [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-10-14 16:16 |只看该作者 |倒序浏览
问题:难道fgets函数也死锁,系统上线后出现过几次这类问题。 暂未解决,只能kill掉读取进程。

环境:HP-UX 安腾 64。
数据文件:放在共享存储上,不在本机硬盘上。
描述:两个并发进程进入文件拆分函数,读取同一待拆分文件,然后就没有下文,僵在里面。
错误跟踪日志如下:

--进程A,GDB堆栈信息
xxxx@/home/db/xxxx> gdb xxxxFileLoad 20166
HP gdb 6.2 for HP Itanium (32 or 64 bit) and target HP-UX 11iv2 and 11iv3.
Copyright 1986 - 2011 Free Software Foundation, Inc.
Hewlett-Packard Wildebeest 6.2 (based on GDB) is covered by the
GNU General Public License. Type "show copying" to see the conditions to
change it and/or distribute copies. Type "show warranty" for warranty/support.
..
Attaching to program: /home/db/xxxx/xxxxbatch/bin/xxxxFileLoad, process 20166

warning: The shared libraries were not privately mapped; setting a
breakpoint in a shared library will not work until you rerun the program;
stepping over longjmp calls will not work as expected.
Please set the kernel variable "shlib_debug_enable" to 1 to enable the shared library debugging

warning: Load module /home/db/oracle/product/10.2.0/lib/libnnz10.so has been stripped.  
Debugging information is not available.

0xc00000000054a490:0 in _read_sys+0x30 () from /usr/lib/hpux64/libc.so.1
(gdb) bt
#0  0xc00000000054a490:0 in _read_sys+0x30 () from /usr/lib/hpux64/libc.so.1
#1  0xc00000000055ed80:0 in read+0xe0 () from /usr/lib/hpux64/libc.so.1
#2  0xc000000000527a20:0 in _filbuf+0x190 () from /usr/lib/hpux64/libc.so.1
#3  0xc00000000053a0d0:0 in __fgets_unlocked+0x1f0 () from /usr/lib/hpux64/libc.so.1
#4  0xc00000000053a3e0:0 in fgets+0x140 () from /usr/lib/hpux64/libc.so.1
#5  0x4000000000030320:0 in g_GetFSegment () at p_file.c:301  文件拆分函数:这一行就是 fgets(),其读取缓存大小为一次读取 400K。
#6  0x4000000000006130:0 in InsxxxxFile () at xxxxFileLoad.pc:1060
#7  0x4000000000005380:0 in main () at xxxxFileLoad.pc:107
(gdb) quit
The program is running.  Quit anyway (and detach it)? (y or n) y
Detaching from program: /home/db/xxxx/xxxxbatch/bin/xxxxFileLoad, process 20166


--进程B,GDB堆栈信息
xxxx@/home/db/xxxx> gdb xxxxFileLoad 20167
HP gdb 6.2 for HP Itanium (32 or 64 bit) and target HP-UX 11iv2 and 11iv3.
Copyright 1986 - 2011 Free Software Foundation, Inc.
Hewlett-Packard Wildebeest 6.2 (based on GDB) is covered by the
GNU General Public License. Type "show copying" to see the conditions to
change it and/or distribute copies. Type "show warranty" for warranty/support.
..
Attaching to program: /home/db/xxxx/xxxxbatch/bin/xxxxFileLoad, process 20167

warning: The shared libraries were not privately mapped; setting a
breakpoint in a shared library will not work until you rerun the program;
stepping over longjmp calls will not work as expected.
Please set the kernel variable "shlib_debug_enable" to 1 to enable the shared library debugging

warning: Load module /home/db/oracle/product/10.2.0/lib/libnnz10.so has been stripped.  
Debugging information is not available.

0xc00000000054a490:0 in _read_sys+0x30 () from /usr/lib/hpux64/libc.so.1
(gdb) bt
#0  0xc00000000054a490:0 in _read_sys+0x30 () from /usr/lib/hpux64/libc.so.1
#1  0xc00000000055ed80:0 in read+0xe0 () from /usr/lib/hpux64/libc.so.1
#2  0xc000000000527a20:0 in _filbuf+0x190 () from /usr/lib/hpux64/libc.so.1
#3  0xc00000000053a0d0:0 in __fgets_unlocked+0x1f0 () from /usr/lib/hpux64/libc.so.1
#4  0xc00000000053a3e0:0 in fgets+0x140 () from /usr/lib/hpux64/libc.so.1
#5  0x4000000000030320:0 in g_GetFSegment () at p_file.c:301 文件拆分函数:这一行就是 fgets(),其读取缓存大小为一次读取 400K。
#6  0x4000000000006130:0 in InsxxxxFile () at xxxxFileLoad.pc:1060
#7  0x4000000000005380:0 in main () at xxxxFileLoad.pc:107
(gdb) quit
The program is running.  Quit anyway (and detach it)? (y or n) y
Detaching from program: /home/db/xxxx/xxxxbatch/bin/xxxxFileLoad, process 20167

请教一下可能是什么原因导致此类问题随机产生。

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
2 [报告]
发表于 2013-10-15 12:53 |只看该作者
man手冊里说明了可以用*_unlocked()來做非阻塞操作。

论坛徽章:
0
3 [报告]
发表于 2013-10-16 08:59 |只看该作者
因为fgets的读操作(read系统调用)是在网络设备上读取文件导致永远阻塞(就是死锁)。

APUE 14.2中描述
  1. 低速系统调用是可能会使进程永远阻塞的一类系统调用,它们包括下列调用:
  2.   * 如果某些文件类型(例如管道、终端设备和[color=Red]网络设备[/color])的数据并不存在,则读操作可能会使调用者永远阻塞。
  3.   * 。。。。
复制代码
你的系统使用的共享存储,它不是本地文件系统,所以它属于低速设备。

另外,APUE 中还说
  1. 我们也曾说过,虽然读、写磁盘文件会使调用者在短暂时间内阻塞,但并不能将和磁盘I/O有关的系统调用视为“低速”。
复制代码
这一点我不能给出进一步解释,为何磁盘文件不属于“低速”,它是否会永远阻塞,我没有找到明确的答案。
望得到指点。。。

论坛徽章:
0
4 [报告]
发表于 2013-10-16 13:30 |只看该作者
意思是:网络设备可能在某一时点失效,从而使读取发生死锁,可以采用 fgets_unlocked 来规避?
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP