??xml version="1.0" encoding="utf-8" standalone="yes"?>97香蕉久久夜色精品国产 ,久久中文字幕无码专区,亚洲人成网亚洲欧洲无码久久http://m.shnenglu.com/mysileng/category/20298.htmlzh-cnTue, 15 Jan 2013 12:48:07 GMTTue, 15 Jan 2013 12:48:07 GMT60select函数与stdioL(fng)的不良后?(?http://m.shnenglu.com/mysileng/archive/2013/01/15/197284.html鑫龙鑫龙Tue, 15 Jan 2013 05:09:00 GMThttp://m.shnenglu.com/mysileng/archive/2013/01/15/197284.htmlhttp://m.shnenglu.com/mysileng/comments/197284.htmlhttp://m.shnenglu.com/mysileng/archive/2013/01/15/197284.html#Feedback0http://m.shnenglu.com/mysileng/comments/commentRss/197284.htmlhttp://m.shnenglu.com/mysileng/services/trackbacks/197284.html
     今天在看UNP6.5节,学习(fn)C(jin)select与stdioL(fng)的后果。特此进E实验一番。再实验之前需明确一下几点:(x)
1.stdio的i/o函数 ?pȝi/o函数不同。stdio函数在用户I间和内栔R有缓Ԍpȝi/o函数只在内核有缓Ԍ用户I间没有?br />
2.stdio的i/o函数~冲机制Q在面对文g时候用的是全缓Ԍ面对讑֤的时候用的行~冲?{下试验用的是键盘和屏幕)Q所以实验用的stdio函数采用行行~冲?br />
3.select函数对于某一个描q符是否准备好可d写,是对内核~冲Z的数据是否达到某一个最低标准,而不是用L(fng)冲区。也是说select函数不知道用L(fng)冲区的存在?br />
首先写了(jin)一个系li/o函数 单的select函数E序Q?br />
     E序lselect函数只设|的键盘的描q符。也是说如果键盘的描述W准备好?jin)就不再d。但是这里有一个问题,解除d后,我们最多只从内核缓冲区?个字节,q个时候就?x)有两个情况Q?br />Q?Q内核空间本来存储的数据小于等?个字节,全被读走。那下次再次调用select函数Q应该肯定会(x)d的,因ؓ(f)键盘输入的内核缓冲区已经没有数据?jin)?br />情况如下(内核I间只有3个字节:(x)1 2 \n):


Q?Q如果内核空间的数据多余3个字节,但是因ؓ(f)最多只能读3个字节,必导致内怸有数据读不完。那么下ơ再遇到select函数的时候是否会(x)d呢?
情况见下:

     当我们输?个字W时?1 2 3 4 \n)Q第一ơread?个字W,内核I间q剩?个字W,然后再次到select函数Q默认情况下如果键盘内核I间字符数大?Qselect是不?x)阻塞键盘描q符的。结果也印证?jin),又read?个字节,q没有堵塞?br />      lg所qselect是可以看见内核空间的~冲区的。那到底能不能看见用L(fng)间缓冲区呢?我们换成stdio的i/o函数l箋实验?br />
--------------------------------------------------------------------
stdio的i/o函数使用select函数的程序如下:(x)


E序用stdio的getc函数从键盘读数据Q运行结果如下:(x)

   我们输入5个字W?1 2 3 4 \n),l果只输Z(jin)1个字W,然后阻塞了(jin)。我们分析一?首先输入5个字W,q?个字W被攑օ用户~冲区,因ؓ(f)最后一个是换行Wƈ且stdio面对讑֤使用行缓冲机Ӟ所以这5个字W马上接着被从用户~冲区刷入内核缓冲区。然后调用select函数Qselect函数发现内核I间中有数据Q于是不dq回。接着getc函数从用L(fng)间输出缓冲区取一个字W,因ؓ(f)用户I间输出~冲区没有数据,于是把内核空间的数据调入一行给用户I间输出~冲区,然后getcq回。接着又碰上select函数Q因为内核缓冲空间的数据已经被放入用L(fng)间输出缓冲区?jin),所以内核缓冲没有数据,那么select认ؓ(f)键盘没有准备好,所以阻塞。虽焉塞了(jin)Q但需要注意的时候这个时候,用户I间是有4个字W数据的Q被select函数无视?jin)?br />
     接下来假设我们再输入2个字W?1 \n),会(x)发生什么呢Q?br />
    输出一对东西,q是怎么回事Q我们l分析。当输入2个字W?1 \n)的时候,内核I间~冲没有数据Q用L(fng)间输出缓冲有4个字W?个字W根据上一D同样原理,被刷入内核空间缓冲区。select函数被调用,发现?个字W,于是不阻塞返回。getc函数从用戯出缓冲取Z个字W,打印stardard... --2然后q回。再ơ@环,调用select函数。关键来?jin),q里跟上ơ不一样了(jin)。这个时候内核空间的~冲中还有上ơ遗留的2个字W,所以依然不dq回Q调用getc函数l箋打印。。。这里的关键是,getc函数。getc函数在用戯出缓冲中有数据的时候,不会(x)把内核空间缓冲中的数据移入用L(fng)间的输出~冲Q得内核空间缓冲一直留有数据。这会(x)持箋到用L(fng)间输出缓冲的数据被取完ؓ(f)止。所以上q奇怪的打印l果可以解释的?jin)?br />lg所qͼselect函数实是看不见用户I间~冲的寻在的?br />

所以如果在使用select函数的时候,要}慎用stdio函数?img src ="http://m.shnenglu.com/mysileng/aggbug/197284.html" width = "1" height = "1" />

鑫龙 2013-01-15 13:09 发表评论
]]>
q程q发服务器中Qsigchld信号引发的血案?(?http://m.shnenglu.com/mysileng/archive/2013/01/11/197202.html鑫龙鑫龙Fri, 11 Jan 2013 10:54:00 GMThttp://m.shnenglu.com/mysileng/archive/2013/01/11/197202.htmlhttp://m.shnenglu.com/mysileng/comments/197202.htmlhttp://m.shnenglu.com/mysileng/archive/2013/01/11/197202.html#Feedback0http://m.shnenglu.com/mysileng/comments/commentRss/197202.htmlhttp://m.shnenglu.com/mysileng/services/trackbacks/197202.html
     讨论两个由sigchld信号引v的血案问题,讨论的环境是服务端的q发E序。我们先把最原始的服务器端ƈ发程序模型脓(chung)出来Q?br />
     以上是服务器端程序,我们先不看被注视掉的部分Q程序对于每一个accept的TCPq接?x)生一个子q程Q交l子q程d理。而子q程其实q不做什么,直接睡眠3U就l束。可以想象这样当子进Eexit以后Q会(x)l父q程发sigchld信号Q通知父进E自己挂?jin)。但是在我们的父q程中,我们对于sigchld信号采用默认处置(忽略)。结果可惌知是来一个连接,׃生一个僵死进E。我们运行程?ơ,看看是否?x)得?个僵死进E?br />服务器端q行E序Q被某客L(fng)q接3ơ:(x)

客户端运行程序执?ơ,q查看进E情?

    首先声明Q我们用客户端可以查看服务器端进E的原因是,我们把客L(fng)和服务端攑֜?jin)一台电(sh)脑上q程本次试验。我们ƈ不关?j)cli客户端的具体实现Q因为服务器q不从客L(fng)获取M信息?br />    从结果可知,果然服务端果断生了(jin)3个僵死进E。接下来我们加上对sigchld的处理程序。但加上以后也将产生我们的第一个血案:(x)

白色为客L(fng)Q黑为服务端:

    可见Q僵死进E的问题已经解决Q但q有个潜在的隐藏危机?br />    PHOSIX对于向acceptq种慢速的pȝpȝ调用有一个基本规?apue,unp都有涉及(qing))Q当q程d于某个慢pȝ调用的时?我们的程序是accept)Q当q程捕捉到某个信?我们的程序是sigchld)Qƈ从信L(fng)处理函数q回?我的E序是deal函数),q程不再d与之前的慢速系l调用,而是q回一个EINTER错误?br />     对于上面的这个规则,各个操作pȝ的对待方式是不同的。有的操作系l返回EINTER以后Q就?x)自动重启之前的慢速系l调用而l,有些则不?x)自动重启。对我们实验E序的这个操作系l环?centos5.5)Q从l果来看,因ؓ(f)q没打印"accept error"q出程序,我猜惻Icentos5.5应该是会(x)自动重启慢速系l调用的。也是说在q里我因为操作系l的优秀Q躲q一?w过W一ơ血?。但Z(jin)可移植性我们应该改q程序ؓ(f)以下实现Q?br />
    我的改动主要集中在对accpt的错误处理里面。接下来阐述另外一个血?br />----------------------------------------------------------------------------
    我们l箋沿用上述的最后一ơ服务端E序来进行接下来的实验,现在我们~写一个客L(fng)E序Q客L(fng)一ơ性跟服务端申?个连接。客L(fng)的程序如?

   整个E序的构架大概如?

    q里客户端最需要注意的是程序的最后一句ƈ不是一个个close所有的套接字描q符Q而是调用exitE序l束q程。根据APUE描述Qexitpȝ调用?x)执行关闭该q程所有描q符的操作,也就是说客户端的所有描q符Q包括套接字描述W也被几乎同时关闭了(jin)。也是说服务端的由监听q程产生的所有处理子q程也会(x)在几乎同时死掉。那么就?x)在几乎同时l父q程发送sigchld信号。情况如?

    血案即发生。请注意Q根据APUE对于信号?-31之内的的信号Q因为历史原因,是不可靠信号Q也pQSIGCHLD信号在被递送到正在dSIGCHLD信号的进E时Q是不会(x)排队的,而是?x)被pȝ压羃。上q问题就是当5个sigchld信号几乎同时到达父进E时Q只有第一个能利被父q程的信号处理函数处理。又因ؓ(f)被signal/sigaction讄的信号处理函C(x)自动d正在处理的信可一原则Q接下来没被处理?个sigchld信号Q被排在?jin)父q程门口。不巧的是,sigchld又是不可靠信Pl果?个sigchld被压~成一个sigchld信号。这导致信L(fng)丢失。也因ؓ(f)丢失?个sigchld信号Q就?x)?个僵进E。你说这是不是一个名W其实的血案。接下来我们实验一下:(x)

    可以清晰的看到结果如预期Q所有出C号丢失导?个僵死进E。那么怎么解决q个问题呢?~。。。?img src ="http://m.shnenglu.com/mysileng/aggbug/197202.html" width = "1" height = "1" />

鑫龙 2013-01-11 18:54 发表评论
]]>
关于U程与信号处理函数获得同一把互斥锁的问?(?http://m.shnenglu.com/mysileng/archive/2013/01/05/196971.html鑫龙鑫龙Sat, 05 Jan 2013 05:46:00 GMThttp://m.shnenglu.com/mysileng/archive/2013/01/05/196971.htmlhttp://m.shnenglu.com/mysileng/comments/196971.htmlhttp://m.shnenglu.com/mysileng/archive/2013/01/05/196971.html#Feedback0http://m.shnenglu.com/mysileng/comments/commentRss/196971.htmlhttp://m.shnenglu.com/mysileng/services/trackbacks/196971.html    刚写?jin)程序发现点问题。假设一个程序有多个U程Q有一个全局互斥锁M....在某U程A获得锁以后,q个时候来?jin)一个信?假设q个信号注册?jin)自q处理E序)Q那么需要进入信号处理程序,q入以后信号处理处理E序也要获得q个锁。问题来?jin)?会(x)死锁么Q?br />    我们知道同一U程如果重复甌同一个互斥锁那么必然?x)死锁?q里问题转换C号处理函数跟之前的线EA?x)是同一个线E上下文么(x同一个线E么Q?我们试验一下。实验之前需要明几点:(x)
    1.Ҏ(gu)APUE 12.8Q进E的处理函数与处理方式是q程中所有线E共享的?br />    2.Ҏ(gu)APUE 12.8Q如果进E接收到信号Q该信号只会(x)被递送到某一个单独线E。一般情况下由那个线E引起信号则递送到那个U程。如果没有线E引发信P信号被发送到LU程?br />


     上面E序首先׃n?jin)一个共同的SIGUSR1信号处理函数Q主控线EA然后产生一个线EBQ线EB首先获得全局互斥锁,然后q行一个长5U的E序Q然后释N。在Bq行?jin)大?U的时候,U程Al本q程(注意是进E,而不是某U程)发送一个SIGUSR1信号。此Ӟ?x)死锁么Q编译运行看l果.

    q箋q行?ơ,都没有死锁。我们分析一下,当进E接收信hQ进E把信号q没有递送给U程B(因ؓ(f)没有产生死锁)Q也是说是不是q个递送过E被优化?jin)?q是我们真的q气好?需要进一步探查。接下来我们指定把信号递送给U程BQ看?x)不会(x)死锁?br />
    接下来编译运行:(x)

    不出意料Q果然死锁了(jin)?br />    也就是说Q关于线E与信号处理函数获得同一把互斥锁的问题,关键是看信号被递送给?jin)那个线E,如果信号是被递送给?jin)获得锁的那个线E,׃(x)死锁Q如果不是之前获得锁的线E,E序ql运行?img src ="http://m.shnenglu.com/mysileng/aggbug/196971.html" width = "1" height = "1" />

鑫龙 2013-01-05 13:46 发表评论
]]>
Ұ¾þ| AVݺɫۺϾþ| þþWWWëƬ| þˬ˸߳AV| һŮȫƾþƬ | ƷŷþþӰ| Ļһþվ| þۺ97ɫֱ| ҹƷþþþþþ| þþþAVۺϲҰ| þþ޾Ʒ| ŷպĻþþò| ƷŮþþþ| þĻƷһ| þúݺɫۺ| ɫۺϾþ| Ѿþþþþ| AVɫۺϾþAVɫۺ| þAV뾫Ʒɫҹ | ˾þô߽AV| þþƷ| ƷþӰԺ| þ99Ʒþþþ| ˾þô߽AVۺӰԺ| 99þþƷþþþþ崿| þùŷպƷ| ɫ͵͵͵þ˴ý| ĻƷѾþ| 鶹ھƷþþþþ| Ʒþˬۺ| þþݾþþ| VVþþ| þ99Ʒþþþþö̬ͼ| ŷ޷avþò| þþƷþþþùۿ99ˮ| Ʒľþþþþþ| 鶹WWWþöڲƷ| ަvþþ| ɫAVԾþþþþ| þþƷ| ҰĻþ|