?? 11.html
字號:
}<br>void reader_function(void)<br>{<br>w h i l e ( 1 )<br>{<br>semaphore_down( &readers_turn );<br>consume_item( buffer );<br>semaphore_up( &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( &child_counter );<br>semaphore_init( &worlds_turn );<br>semaphore_down( &worlds_turn ); /* world goes second */<br>semaphore_decrement( &child_counter ); /* value now 0 */<br>semaphore_decrement( &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( &thread1, pthread_attr_default,<br>(void *) &print_message_function, (void *) message1);<br>semaphore_down( &worlds_turn );<br>pthread_create(&thread2, pthread_attr_default,<br>(void *) &print_message_function, (void *) message2);<br>semaphore_down( &child_counter );<br>/* not really necessary to destroy since we are exiting anyway */<br>semaphore_destroy ( &child_counter );<br>semaphore_destroy ( &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( &worlds_turn );<br>semaphore_up( &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( &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->v = 1;<br>if (pthread_mutex_init (&(s->mutex), pthread_mutexattr_default) == -1)<br>do_error ("Error setting up semaphore mutex");<br>if (pthread_cond_init (&(s->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 (&(s->mutex)) == -1)<br>do_error ("Error destroying semaphore mutex");<br>if (pthread_cond_destroy (&(s->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 (&(s->mutex));<br>( s - > v ) + + ;<br>value_after_op = s->v;<br>tw_pthread_mutex_unlock (&(s->mutex));<br>tw_pthread_cond_signal (&(s->cond));<br>return (value_after_op);<br>}<br>/ *<br>* function decrements the semaphore and blocks if the semaphore is<br>* <= 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 (&(s->mutex));<br>while (s->v <= 0)<br>{<br>tw_pthread_cond_wait (&(s->cond), &(s->mutex));<br>}<br>( s - > v ) - - ;<br>value_after_op = s->v;<br>tw_pthread_mutex_unlock (&(s->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 (&(s->mutex));<br>s - > v - - ;<br>value_after_op = s->v;<br>tw_pthread_mutex_unlock (&(s->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 (&(s->mutex));<br>value_after_op = s->v;<br>tw_pthread_mutex_unlock (&(s->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>exit (1);<br>}<p><p><p><center><A HREF="#Content">[目錄]</A></center><hr><br><A NAME="I263" ID="I263"></A><center><b><font size=+2>代碼例子</font></b></center><br><center><A HREF="#Content">[目錄]</A></center><hr><br><A NAME="I264" ID="I264"></A><center><b><font size=+2>newthread</font></b></center><br>/***********************************************************************<br> Case study source code from the book `The Linux A to Z'<br> by Phil Cornes. Published by Prentice Hall, 1996.<br> Copyright (C) 1996 Phil Cornes<p> This program is free software; you can redistribute it and/or modify<br> it under the terms of the GNU General Public License as published by<br> the Free Software Foundation; either version 2 of the License, or<br> (at your option) any later version.<p> This program is distributed in the hope that it will be useful,<br> but WITHOUT ANY WARRANTY; without even the implied warranty of<br> MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the<br> GNU General Public License for more details.<p> You should have received a copy of the GNU General Public License<br> along with this program; if not, write to the Free Software<br> Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.<br>***********************************************************************/<p>new_thread(int (*start_addr)(void), int stack_size)<br>{<br> struct context *ptr;<br> int esp;<p> /* 1 */<br> if (!(ptr = (struct context *)malloc(sizeof(struct context))))<br> return 0;<p> /* 2 */<br> if (!(ptr->stack = (char *)malloc(stack_size)))<br> &
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -