<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>中文 &#187; zhongguo</title>
	<atom:link href="http://software.intel.com/zh-cn/blogs/author/zhongguo/feed/" rel="self" type="application/rss+xml" />
	<link>http://software.intel.com/zh-cn/blogs</link>
	<description></description>
	<lastBuildDate>Mon, 28 May 2012 14:23:20 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.3</generator>
		<item>
		<title>linux 多线程编程 之 信号量互斥同步</title>
		<link>http://software.intel.com/zh-cn/blogs/2011/12/02/linux-3/</link>
		<comments>http://software.intel.com/zh-cn/blogs/2011/12/02/linux-3/#comments</comments>
		<pubDate>Fri, 02 Dec 2011 09:10:48 +0000</pubDate>
		<dc:creator>zhongguo</dc:creator>
				<category><![CDATA[博客征文专栏]]></category>
		<category><![CDATA[开放源代码]]></category>
		<category><![CDATA[移动技术]]></category>

		<guid isPermaLink="false">http://software.intel.com/zh-cn/blogs/2011/12/02/linux-3/</guid>
		<description><![CDATA[  本文在上一篇的基础上进一步说明，Linux下多线程编程的互斥与同步。上一篇实现线程之间同步采用了互斥锁，同步采用条件变量，本文将说明如何使用信号量实现线程之间的互斥与同步。互斥锁只有0，1两中状态，适合于线程对共享资源的独占访问，很多时候每个资源可以同时被有限的线程访问，此时互斥锁将无法满足；条件变量同步也同样存在这种问题。信号量实际是一种非负整型计数器，可以很好的控制线程之间资源访问，互斥锁能实现的功能，信号量同样可以。 信号量控制资源共享主要是PV原语操作， PV原语是对整数计数器信号量sem的操作。一次 P操作使 sem减一，而一次 V操作使sem 加一。进程（或线程）根据信号量的值来判断是否对公共资源具有访问权限。当信号量sem 的值大于等于零时，该进程（或线程）具有公共资源的访问权限；相反，当信号量 sem的值小于零时，该进程（或线程）就将阻塞直到信号量 sem的值大于等于 0 为止。 Linux 实现了POSIX 的无名信号量，主要用于线程间的互斥同步。这里主要介绍几个常见函数。 · sem_init用于创建一个信号量，并能初始化它的值。 · sem_wait和sem_trywait相当于P操作，它们都能将信号量的值减一，两者的区别在 于若信号量小于零时，sem_wait将会阻塞进程，而 sem_trywait则会立即返回。 · sem_post相当于V操作，它将信号量的值加一同时发出信号唤醒等待的进程。 · sem_getvalue用于得到信号量的值。 · sem_destroy用于删除信号量。 所需头文件 #include 函数原型 int sem_init(sem_t *sem,int pshared,unsigned int value) sem：信号量 pshared：决定信号量能否在几个进程间共享。由于目前Linux还没有实现进程间共享信号量，所以这个值只能够取0 value：信号量初始化值 函数返回值 成功：0 ，出错：-1 所需头文件 #include 函数原型 int sem_wait(sem_t *sem) int sem_trywait(sem_t *sem) int sem_post(sem_t *sem) [...]]]></description>
			<content:encoded><![CDATA[<p> </p>
<p>本文在上一篇的基础上进一步说明，Linux下多线程编程的互斥与同步。上一篇实现线程之间同步采用了互斥锁，同步采用条件变量，本文将说明如何使用信号量实现线程之间的互斥与同步。互斥锁只有0，1两中状态，适合于线程对共享资源的独占访问，很多时候每个资源可以同时被有限的线程访问，此时互斥锁将无法满足；条件变量同步也同样存在这种问题。信号量实际是一种非负整型计数器，可以很好的控制线程之间资源访问，互斥锁能实现的功能，信号量同样可以。</p>
<p>信号量控制资源共享主要是PV原语操作， PV原语是对整数计数器信号量sem的操作。一次 P操作使 sem减一，而一次 V操作使sem 加一。进程（或线程）根据信号量的值来判断是否对公共资源具有访问权限。当信号量sem 的值大于等于零时，该进程（或线程）具有公共资源的访问权限；相反，当信号量 sem的值小于零时，该进程（或线程）就将阻塞直到信号量 sem的值大于等于 0 为止。</p>
<p>Linux 实现了POSIX 的无名信号量，主要用于线程间的互斥同步。这里主要介绍几个常见函数。<br />
· sem_init用于创建一个信号量，并能初始化它的值。<br />
· sem_wait和sem_trywait相当于P操作，它们都能将信号量的值减一，两者的区别在 于若信号量小于零时，sem_wait将会阻塞进程，而 sem_trywait则会立即返回。<br />
· sem_post相当于V操作，它将信号量的值加一同时发出信号唤醒等待的进程。<br />
· sem_getvalue用于得到信号量的值。<br />
· sem_destroy用于删除信号量。<br />
所需头文件 #include</p>
<p>函数原型 int sem_init(sem_t *sem,int pshared,unsigned int value)<br />
sem：信号量<br />
pshared：决定信号量能否在几个进程间共享。由于目前Linux还没有实现进程间共享信号量，所以这个值只能够取0<br />
value：信号量初始化值<br />
函数返回值 成功：0 ，出错：-1</p>
<p>所需头文件 #include<br />
函数原型<br />
int sem_wait(sem_t *sem)<br />
int sem_trywait(sem_t *sem)<br />
int sem_post(sem_t *sem)<br />
int sem_getvalue(sem_t *sem)<br />
int sem_destroy(sem_t *sem)<br />
函数传入值 sem：信号量<br />
函数返回值 成功：0 ，出错：-1</p>
<p>从上面函数来看，实现线程之间同步信号量比互斥锁使用起来相对容易一些，操作简单，容易理解，适用范围广。</p>
<p>下面上一篇的问题用信号量来实现，线程使用部分没变，主要改变了对资源的控制方式：（代码本人亲自编译通过）</p>
<p>view plaincopy to clipboardprint?<br />
01.#include<br />
02.#include<br />
03.#include<br />
04.#include<br />
05.#include<br />
06.#include<br />
07.<br />
08.int g_Flag = 0;<br />
09.sem_t sem_mutex; // 用于互斥<br />
10.sem_t sem_syn; // 用于同步<br />
11.<br />
12.void *thread1( void *arg );<br />
13.void *thread2( void *arg );<br />
14.int main()<br />
15.{<br />
16. pthread_t tid1, tid2;<br />
17. int rc1, rc2;<br />
18.<br />
19. sem_init( &amp;sem_mutex, 0, 1 );<br />
20. sem_init( &amp;sem_syn, 0, 0 );<br />
21. printf( " Inter main !\n" );<br />
22.<br />
23. rc2 = pthread_create( &amp;tid2, NULL, thread2, NULL );<br />
24. if( rc2 != 0 )<br />
25. printf( " %s, %d \n", __func__, strerror( rc2 ) );<br />
26.<br />
27. rc1 = pthread_create( &amp;tid1, NULL, thread1, &amp;tid2 );<br />
28. if( rc1 != 0 )<br />
29. printf( " %s, %d \n", __func__, strerror(rc1) );<br />
30. printf( " Leave main!\n\n" );<br />
31.<br />
32. sem_wait( &amp;sem_syn ); // 同步等待，阻塞<br />
33. exit( 0 );<br />
34.}<br />
35.<br />
36.void *thread1( void *arg )<br />
37.{<br />
38. pthread_t *ptid = NULL;<br />
39. printf( " Enter thread1\n" );<br />
40. printf( " thread1 id: %u, g_Flag: %d \n", ( unsigned int )pthread_self(), g_Flag );<br />
41.<br />
42. if( sem_wait( &amp;sem_mutex ) != 0)<br />
43. {<br />
44. perror(" pthread1 sem_mutex\n");<br />
45. }<br />
46.<br />
47. if( g_Flag == 2 )<br />
48. sem_post( &amp;sem_syn );<br />
49. g_Flag = 1;<br />
50.<br />
51. if( sem_post( &amp;sem_mutex ) != 0)<br />
52. {<br />
53. perror( "pthread1 sem_post\n" );<br />
54. }<br />
55. printf( " thread1 id: %u, g_Flag: %d \n",( unsigned int )pthread_self(), g_Flag );<br />
56. printf( "Leave thread1 \n\n" );<br />
57.<br />
58. ptid = ( pthread_t *)arg;<br />
59. printf( " ptid = %u \n", *ptid );<br />
60. pthread_join( *ptid, NULL );<br />
61. pthread_exit(0 );<br />
62.}<br />
63.<br />
64.void *thread2( void *arg )<br />
65.{<br />
66. printf( " Enter thread2 !\n" );<br />
67. printf( " thread2 id: %u , g_Flag: %d \n", ( unsigned int)pthread_self(), g_Flag );<br />
68.<br />
69. if( sem_wait( &amp;sem_mutex ) != 0 )<br />
70. {<br />
71. perror( "thread2 sem_wait \n" );<br />
72. }<br />
73.<br />
74. if( g_Flag == 1 )<br />
75. sem_post( &amp;sem_syn );<br />
76.<br />
77. g_Flag = 2;<br />
78.<br />
79. if( sem_post( &amp;sem_mutex ) != 0)<br />
80. {<br />
81. perror( " thread2 sem_post\n" );<br />
82. }<br />
83. printf( " thread2 id: %u , g_Flag: %d \n", ( unsigned int )pthread_self(), g_Flag );<br />
84. printf( "Leave thread2 \n\n" );<br />
85.<br />
86. pthread_exit(0);<br />
87.}</p>
]]></content:encoded>
			<wfw:commentRss>http://software.intel.com/zh-cn/blogs/2011/12/02/linux-3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

