<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
<channel>
<title><![CDATA[向东博客 专注WEB应用 构架之美 --- 构架之美，在于尽态极妍 | 应用之美，在于药到病除]]></title> 
<link>http://www.jackxiang.com/index.php</link> 
<description><![CDATA[赢在IT，Playin' with IT,Focus on Killer Application,Marketing Meets Technology.]]></description> 
<language>zh-cn</language> 
<copyright><![CDATA[向东博客 专注WEB应用 构架之美 --- 构架之美，在于尽态极妍 | 应用之美，在于药到病除]]></copyright>
<item>
<link>http://www.jackxiang.com/post//</link>
<title><![CDATA[（转）关于信号量sem_wait的整理]]></title> 
<author>jack &lt;xdy108@126.com&gt;</author>
<category><![CDATA[Unix/LinuxC技术]]></category>
<pubDate>Fri, 06 Feb 2015 09:25:08 +0000</pubDate> 
<guid>http://www.jackxiang.com/post//</guid> 
<description>
<![CDATA[ 
	<br/>SYNOPSIS<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #include &lt;semaphore.h&gt;<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int sem_init(sem_t *sem, int pshared, unsigned int value);<br/>//初始化信号量<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int sem_wait(sem_t * sem);<br/>//等待信号,获取拥有权<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int sem_trywait(sem_t * sem);<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int sem_post(sem_t * sem);<br/>//发出信号即释放拥有权<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int sem_getvalue(sem_t * sem, int * sval);<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int sem_destroy(sem_t * sem);<br/>//注销信号量,在linux中其本质是没有任何作用的，它不做任何事情。<br/>DESCRIPTION<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; This manual page documents POSIX 1003.1b semaphores, not to be confused with SystemV semaphores as described in ipc(5),<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; semctl(2) and semop(2).<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Semaphores are counters for resources shared between threads. The basic operations on semaphores are: increment the<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; counter atomically, and wait until the counter is non-null and decrement it atomically.<br/>//信号量是在多线程环境中共享资源的计数器。对信号量的基本操作无非有三个：对信号量的增加；然后阻塞线程等待，直到信号量不为空才返回；然后就是对信号量的减少。<br/>// 在编程中，信号量最常用的方式就是一个线程A使用sem_wait阻塞，因为此时信号量计数为0，直到另外一个线程B发出信号post后，信号量计数加 1，此时，线程A得到了信号，信号量的计数为1不为空，所以就从sem_wait返回了，然后信号量的计数又减1变为零。<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sem_init initializes the semaphore object pointed to by sem. The count associated with the semaphore is set initially to<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; value. The pshared argument indicates whether the semaphore is local to the current process ( pshared is zero) or is to<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; be shared between several processes ( pshared is not zero). LinuxThreads currently does not support process-shared<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; semaphores, thus sem_init always returns with error ENOSYS if pshared is not zero.<br/>//在使用信号量之前，我们必须初始化信号。第三个参数通常设置为零，初始化信号的计数为0，这样第一次使用sem_wait的时候会因为信号计数为0而等待，直到在其他地方信号量post了才返回。除非你明白你在干什么，否则不要将第三个参数设置为大于0的数。<br/>//第二个参数是用在进程之间的数据共享标志，如果仅仅使用在当前进程中，设置为0。如果要在多个进程之间使用该信号，设置为非零。但是在Linux线程中，暂时还不支持进程之间的信号共享，所以第二个参数说了半天等于白说，必须设置为0.否则将返回ENOSYS错误。<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sem_wait suspends the calling thread until the semaphore pointed to by sem has non-zero count. It then atomically<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; decreases the semaphore count.<br/>//当信号的计数为零的时候，sem_wait将休眠挂起当前调用线程，直到信号量计数不为零。在sem_wait返回后信号量计数将自动减1.<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sem_trywait is a non-blocking variant of sem_wait. If the semaphore pointed to by sem has non-zero count, the count is<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; atomically decreased and sem_trywait immediately returns 0. If the semaphore count is zero, sem_trywait immediately<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; returns with error EAGAIN.<br/>//sem_trywait是一个立即返回函数，不会因为任何事情阻塞。根据其返回值得到不同的信息。如果返回值为0，说明信号量在该函数调用之前大于0，但是调用之后会被该函数自动减1.至于调用之后是否为零则不得而知了。如果返回值为EAGAIN说明信号量计数为0。<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sem_post atomically increases the count of the semaphore pointed to by sem. This function never blocks and can safely be<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; used in asynchronous signal handlers.<br/>//解除信号量等待限制。让信号量计数加1.该函数会立即返回不等待。<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sem_getvalue stores in the location pointed to by sval the current count of the semaphore sem.<br/>//获得当前信号量计数的值。<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sem_destroy destroys a semaphore object, freeing the resources it might hold. No threads should be waiting on the<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; semaphore at the time sem_destroy is called. In the LinuxThreads implementation, no resources are associated with<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; semaphore objects, thus sem_destroy actually does nothing except checking that no thread is waiting on the semaphore.<br/>// 销毁信号量对象，释放信号量内部资源。然而在linux的线程中，其实是没有任何资源关联到信号量对象需要释放的，因此在linux中，销毁信号量对象的 作用仅仅是测试是否有线程因为该信号量在等待。如果函数返回0说明没有，正常注销信号量，如果返回EBUSY，说明还有线程正在等待该信号量的信号。<br/><br/>CANCELLATION<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sem_wait is a cancellation point.<br/><br/>ASYNC-SIGNAL SAFETY<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; On processors supporting atomic compare-and-swap (Intel 486, Pentium and later, Alpha, PowerPC, MIPS II, Motorola 68k),<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; the sem_post function is async-signal safe and can therefore be called from signal handlers. This is the only thread syn-<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; chronization function provided by POSIX threads that is async-signal safe.<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; On the Intel 386 and the Sparc, the current LinuxThreads implementation of sem_post is not async-signal safe by lack of<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; the required atomic operations.<br/>//现在sem_post被POSIX所规范，当它改变信号量计数器值的时候是线程安全的。<br/><br/>RETURN VALUE<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; The sem_wait and sem_getvalue functions always return 0. All other semaphore functions return 0 on success and -1 on<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; error, in addition to writing an error code in errno.<br/>//通常返回值往往都为0，表示成功，如果有误将返回-1，并且将错误的代码号赋值给errno。<br/><br/>ERRORS<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; The sem_init function sets errno to the following codes on error:<br/>//sem_init失败时，常见错误有:<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EINVAL value exceeds the maximal counter value SEM_VALUE_MAX<br/>&nbsp;&nbsp; //第三个参数value值超过了系统能够承受的最大值SEM_VALUE_MAX.<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ENOSYS pshared is not zero<br/>&nbsp;&nbsp; //你将第二参数设置为了非零，如果是linux系统，请将第二个参数设置为零<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; The sem_trywait function sets errno to the following error code on error:<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EAGAIN the semaphore count is currently 0<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; The sem_post function sets errno to the following error code on error:<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ERANGE after incrementation, the semaphore value would exceed SEM_VALUE_MAX (the semaphore count is left unchanged<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; in this case)<br/>&nbsp;&nbsp; //信号量的计数超过了系统能够承受的最大值SEM_VALUE_MAX。<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; The sem_destroy function sets errno to the following error code on error:<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EBUSY some threads are currently blocked waiting on the semaphore.<br/>&nbsp;&nbsp; //某些线程正在使用该信号量等待。<br/><br/>其实线程临界区可以使用信号量来实现，将信号量的信号初始化为1，然后在临界区使用完毕后再置信号量为1我们就可以轻松实现mutex了。<br/><br/>具体实现，自己慢慢琢磨一下吧。<br/><br/>一份好文档，胜读十年书<br/>本文参考了诸多资料，百度百科，cplusplus等：<br/>Linux下进程的同步互斥实例——生产者消费者。<br/>http://www.2cto.com/os/201410/341101.html<br/><br/>可能遇到问题：<br/>在使用sem_wait()阻塞时总是发现在本该阻塞的地方竟然退出了。太假了吧，这样的话sem_wait()也太不靠谱了，究竟是谁让它退出的? 后来在网上查了一下发现原来是调用的方式不太严谨，不能直接就用sem_wait()来作为阻塞时用，因为sem_wait()有可能会被其它信号中断，如EINTR,所以需要将它排除掉。<br/><br/>来自：http://www.cnblogs.com/hnrainll/archive/2011/04/20/2022487.html<br/>参考：http://bbs.csdn.net/topics/390116173
]]>
</description>
</item><item>
<link>http://www.jackxiang.com/post//#blogcomment</link>
<title><![CDATA[[评论] （转）关于信号量sem_wait的整理]]></title> 
<author> &lt;user@domain.com&gt;</author>
<category><![CDATA[评论]]></category>
<pubDate>Thu, 01 Jan 1970 00:00:00 +0000</pubDate> 
<guid>http://www.jackxiang.com/post//#blogcomment</guid> 
<description>
<![CDATA[ 
	
]]>
</description>
</item>
</channel>
</rss>