⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 进程和线程编程.htm

📁 进程与线程编程模式是进行程序开发的基础,次文案详细描述了此项内容
💻 HTM
📖 第 1 页 / 共 5 页
字号:
<CENTER><A 
href="http://www.huihoo.com/joyfire.net/11.html#Content">[目录]</A></CENTER>
<HR>
<BR><A id=I261 name=I261></A>
<CENTER><B><FONT 
size=+2>线程同步</FONT></B></CENTER><BR>POSIX提供两种线程同步的方法,mutex和条件变量。mutex是一种简单的加锁的方法来控制对共享资源的存取。我们可以创建一个读/写程序,它们共用一个共享缓冲区,使用mutex来控制对缓冲区的存取。<BR>void 
reader_function(void);<BR>void writer_function(void);<BR>char buf f e r ;<BR>int 
buffer_has_item = 0;<BR>pthread_mutex_t mutex;<BR>struct timespec 
delay;<BR>main( )<BR>{<BR>pthread_t reader;<BR>delay.tv_sec = 
2;<BR>delay.tv_nsec = 0;<BR>pthread_mutex_init(&amp;mutex, 
pthread_mutexattr_default);<BR>pthread_create( &amp;reader, 
pthread_attr_default, (void*)&amp;reader_function,<BR>N U L L ) 
;<BR>writer_function( )<BR>void writer_function(void)<BR>{<BR>while( 1 
)<BR>{<BR>pthread_mutex_lock( &amp;mutex );<BR>if ( buffer_has_item == 0 
)<BR>{<BR>buffer = make_new_item();<BR>buffer_has_item = 
1;<BR>}<BR>pthread_mutex_unlock( &amp;mutex );<BR>pthread_delay_np( &amp;delay 
);<BR>}<BR>}<BR>void reader_function(void)<BR>{<BR>while( 1 
)<BR>{<BR>pthread_mutex_lock( &amp;mutex );<BR>if ( buffer_has_item == 
1)<BR>{<BR>consume_item( buffer );<BR>buffer_has_item = 
0;<BR>}<BR>pthread_mutex_unlock( &amp;mutex );<BR>pthread_delay_np( &amp;delay 
);<BR>}<BR>}<BR>在上面的程序中,我们假定缓冲区只能保存一条信息,这样缓冲区只有两个状态,有一条信息或者没有信息。使用延迟是为了避免一个线程永远占有mutex。<BR>但mutex的缺点在于它只有两个状态,锁定和非锁定。POSIX的条件变量通过允许线程阻塞和等待另一个线程的信号方法,从而弥补了mutex的不足。当接受到一个信号时,阻塞线程将会被唤起,并试图获得相关的mutex的锁。
<P>
<P>
<P>
<CENTER><A 
href="http://www.huihoo.com/joyfire.net/11.html#Content">[目录]</A></CENTER>
<HR>
<BR><A id=I262 name=I262></A>
<CENTER><B><FONT 
size=+2>使用信号量协调程序</FONT></B></CENTER><BR>我们可以使用信号量重新看一下上面的读/写程序。涉及信号量的操作是semaphore_up、semaphore_down、semaphore_init、semaphore_destroy和semaphore_decrement。所有这些操作都只有一个参数,一个指向信号量目标的指针。<BR>void 
reader_function(void);<BR>void writer_function(void);<BR>char buffer 
;<BR>Semaphore writers_turn;<BR>Semaphore readers_turn;<BR>main( 
)<BR>{<BR>pthread_t reader;<BR>semaphore_init( &amp;readers_turn 
);<BR>semaphore_init( &amp;writers_turn );<BR>/* writer must go first 
*/<BR>semaphore_down( &amp;readers_turn );<BR>pthread_create( &amp;reader, 
pthread_attr_default,<BR>(void *)&amp;reader_function, NULL);<BR>w r i t e r _ f 
u n c t i o n ( ) ;<BR>}<BR>void writer_function(void)<BR>{<BR>w h i l e ( 1 
)<BR>{<BR>semaphore_down( &amp;writers_turn );<BR>b u ffer = 
make_new_item();<BR>semaphore_up( &amp;readers_turn );<BR>}<BR>}<BR>void 
reader_function(void)<BR>{<BR>w h i l e ( 1 )<BR>{<BR>semaphore_down( 
&amp;readers_turn );<BR>consume_item( buffer );<BR>semaphore_up( 
&amp;writers_turn );<BR>}<BR>}<BR>这个例子也没有完全地利用一般信号量的所有函数。我们可以使用信号量重新编写“Hello 
world” 的程序:<BR>void print_message_function( void *ptr );<BR>Semaphore 
child_counter;<BR>Semaphore worlds_turn;<BR>main( )<BR>{<BR>pthread_t thread1, 
thread2;<BR>char *message1 = "Hello";<BR>char *message2 = "Wo r l d " 
;<BR>semaphore_init( &amp;child_counter );<BR>semaphore_init( &amp;worlds_turn 
);<BR>semaphore_down( &amp;worlds_turn ); /* world goes second 
*/<BR>semaphore_decrement( &amp;child_counter ); /* value now 0 
*/<BR>semaphore_decrement( &amp;child_counter ); /* value now -1 */<BR>/*<BR>* 
child_counter now must be up-ed 2 times for a thread blocked on it<BR>* to be 
released<BR>*<BR>* /<BR>pthread_create( &amp;thread1, 
pthread_attr_default,<BR>(void *) &amp;print_message_function, (void *) 
message1);<BR>semaphore_down( &amp;worlds_turn 
);<BR>pthread_create(&amp;thread2, pthread_attr_default,<BR>(void *) 
&amp;print_message_function, (void *) message2);<BR>semaphore_down( 
&amp;child_counter );<BR>/* not really necessary to destroy since we are exiting 
anyway */<BR>semaphore_destroy ( &amp;child_counter );<BR>semaphore_destroy ( 
&amp;worlds_turn );<BR>e x i t ( 0 ) ;<BR>}<BR>void print_message_function( void 
*ptr )<BR>{<BR>char *message;<BR>message = (char *) ptr;<BR>printf("%s ", 
message);<BR>fflush(stdout);<BR>semaphore_up( &amp;worlds_turn 
);<BR>semaphore_up( &amp;child_counter );<BR>p t h r e a d _ e x i t ( 0 ) 
;<BR>}<BR>信号量c h i l d _ c o u n t e r用来强迫父线程阻塞,直到两个子线程执行完p r i n t 
f语句和其后的semaphore_up( &amp;child_counter )语句才继续执行。
<P>Semaphore.h
<P>#ifndef SEMAPHORES<BR>#define SEMAPHORES<BR>#include<BR>#include<BR>typedef 
struct Semaphore<BR>{<BR>int v;<BR>pthread_mutex_t mutex;<BR>pthread_cond_t 
cond;<BR>}<BR>S e m a p h o r e ;<BR>int semaphore_down (Semaphore * s);<BR>int 
semaphore_decrement (Semaphore * s);<BR>int semaphore_up (Semaphore * 
s);<BR>void semaphore_destroy (Semaphore * s);<BR>void semaphore_init (Semaphore 
* s);<BR>int semaphore_value (Semaphore * s);<BR>int tw_pthread_cond_signal 
(pthread_cond_t * c);<BR>int tw_pthread_cond_wait (pthread_cond_t * c, 
pthread_mutex_t * m);<BR>int tw_pthread_mutex_unlock (pthread_mutex_t * 
m);<BR>int tw_pthread_mutex_lock (pthread_mutex_t * m);<BR>void do_error (char 
*msg);<BR># e n d i f
<P>Semaphore.c
<P>#include "semaphore.h"<BR>/ *<BR>* function must be called prior to semaphore 
use.<BR>*<BR>* /<BR>v o i d<BR>semaphore_init (Semaphore * s)<BR>{<BR>s-&gt;v = 
1;<BR>if (pthread_mutex_init (&amp;(s-&gt;mutex), pthread_mutexattr_default) == 
-1)<BR>do_error ("Error setting up semaphore mutex");<BR>if (pthread_cond_init 
(&amp;(s-&gt;cond), pthread_condattr_default) == -1)<BR>do_error ("Error setting 
up semaphore condition signal");<BR>* function should be called when there is no 
longer a need for<BR>* the semaphore.<BR>*<BR>* /<BR>v o i 
d<BR>semaphore_destroy (Semaphore * s)<BR>{<BR>if (pthread_mutex_destroy 
(&amp;(s-&gt;mutex)) == -1)<BR>do_error ("Error destroying semaphore 
mutex");<BR>if (pthread_cond_destroy (&amp;(s-&gt;cond)) == -1)<BR>do_error 
("Error destroying semaphore condition signal");<BR>}<BR>/ *<BR>* function 
increments the semaphore and signals any threads that<BR>* are blocked waiting a 
change in the semaphore.<BR>*<BR>* /<BR>i n t<BR>semaphore_up (Semaphore * 
s)<BR>{<BR>int value_after_op;<BR>tw_pthread_mutex_lock 
(&amp;(s-&gt;mutex));<BR>( s - &gt; v ) + + ;<BR>value_after_op = 
s-&gt;v;<BR>tw_pthread_mutex_unlock 
(&amp;(s-&gt;mutex));<BR>tw_pthread_cond_signal (&amp;(s-&gt;cond));<BR>return 
(value_after_op);<BR>}<BR>/ *<BR>* function decrements the semaphore and blocks 
if the semaphore is<BR>* &lt;= 0 until another thread signals a 
change.<BR>*<BR>* /<BR>i n t<BR>semaphore_down (Semaphore * s)<BR>{<BR>int 
value_after_op;<BR>tw_pthread_mutex_lock (&amp;(s-&gt;mutex));<BR>while (s-&gt;v 
&lt;= 0)<BR>{<BR>tw_pthread_cond_wait (&amp;(s-&gt;cond), 
&amp;(s-&gt;mutex));<BR>}<BR>( s - &gt; v ) - - ;<BR>value_after_op = 
s-&gt;v;<BR>tw_pthread_mutex_unlock (&amp;(s-&gt;mutex));<BR>return 
(value_after_op);<BR>}<BR>/ *<BR>* function does NOT block but simply decrements 
the semaphore.<BR>* should not be used instead of down -- only for programs 
where<BR>* multiple threads must up on a semaphore before another thread<BR>* 
can go down, i.e., allows programmer to set the semaphore to<BR>* a negative 
value prior to using it for synchronization.<BR>*<BR>* /<BR>i n 
t<BR>semaphore_decrement (Semaphore * s)<BR>{<BR>int 
value_after_op;<BR>tw_pthread_mutex_lock (&amp;(s-&gt;mutex));<BR>s - &gt; v - - 
;<BR>value_after_op = s-&gt;v;<BR>tw_pthread_mutex_unlock 
(&amp;(s-&gt;mutex));<BR>return (value_after_op);<BR>}<BR>/ *<BR>* function 
returns the value of the semaphore at the time the<BR>* critical section is 
accessed. obviously the value is not guarenteed<BR>* after the function unlocks 
the critical section. provided only<BR>* for casual debugging, a better approach 
is for the programmar to<BR>* protect one semaphore with another and then check 
its value.<BR>* an alternative is to simply record the value returned by 
semaphore_up<BR>* or semaphore_down.<BR>*<BR>* /<BR>i n t<BR>semaphore_value 
(Semaphore * s)<BR>{<BR>/* not for sync */<BR>int 
value_after_op;<BR>tw_pthread_mutex_lock (&amp;(s-&gt;mutex));<BR>value_after_op 
= s-&gt;v;<BR>tw_pthread_mutex_unlock (&amp;(s-&gt;mutex));<BR>return 
(value_after_op);<BR>}<BR>/* 
-------------------------------------------------------------------- */<BR>/* 
The following functions replace standard library functions in that */<BR>/* they 
exit on any error returned from the system calls. Saves us */<BR>/* from having 
to check each and every call above. */<BR>/* 
-------------------------------------------------------------------- */<BR>i n 
t<BR>tw_pthread_mutex_unlock (pthread_mutex_t * m)<BR>{<BR>int 
return_value;<BR>if ((return_value = pthread_mutex_unlock (m)) == 
-1)<BR>do_error ("pthread_mutex_unlock");<BR>return (return_value);<BR>}<BR>i n 
t<BR>tw_pthread_mutex_lock (pthread_mutex_t * m)<BR>{<BR>int return_value;<BR>if 
((return_value = pthread_mutex_lock (m)) == -1)<BR>do_error 
("pthread_mutex_lock");<BR>return (return_value);<BR>}<BR>i n 
t<BR>tw_pthread_cond_wait (pthread_cond_t * c, pthread_mutex_t * m)<BR>{<BR>int 
return_value;<BR>if ((return_value = pthread_cond_wait (c, m)) == 
-1)<BR>do_error ("pthread_cond_wait");<BR>return (return_value);<BR>}<BR>i n 
t<BR>tw_pthread_cond_signal (pthread_cond_t * c)<BR>{<BR>int return_value;<BR>if 
((return_value = pthread_cond_signal (c)) == -1)<BR>do_error 
("pthread_cond_signal");<BR>return (return_value);<BR>}<BR>/ *<BR>* function 
just prints an error message and exits<BR>*<BR>* /<BR>v o i d<BR>do_error (char 
*msg)<BR>{<BR>perror (msg);<BR

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -