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

📄 11.html

📁 介绍linux下文件和设备编程
💻 HTML
📖 第 1 页 / 共 5 页
字号:
}<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 = &quot;Hello&quot;;<br>char *message2 = &quot;Wo r l d &quot; ;<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(&quot;%s &quot;, 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 &quot;semaphore.h&quot;<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 (&quot;Error setting up semaphore mutex&quot;);<br>if (pthread_cond_init (&amp;(s-&gt;cond), pthread_condattr_default) == -1)<br>do_error (&quot;Error setting up semaphore condition signal&quot;);<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 (&quot;Error destroying semaphore mutex&quot;);<br>if (pthread_cond_destroy (&amp;(s-&gt;cond)) == -1)<br>do_error (&quot;Error destroying semaphore condition signal&quot;);<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 (&quot;pthread_mutex_unlock&quot;);<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 (&quot;pthread_mutex_lock&quot;);<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 (&quot;pthread_cond_wait&quot;);<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 (&quot;pthread_cond_signal&quot;);<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>&nbsp;&nbsp;&nbsp; Case study source code from the book `The Linux A to Z'<br>&nbsp;&nbsp;&nbsp; by Phil Cornes. Published by Prentice Hall, 1996.<br>&nbsp;&nbsp;&nbsp; Copyright (C) 1996 Phil Cornes<p>&nbsp;&nbsp;&nbsp; This program is free software; you can redistribute it and/or modify<br>&nbsp;&nbsp;&nbsp; it under the terms of the GNU General Public License as published by<br>&nbsp;&nbsp;&nbsp; the Free Software Foundation; either version 2 of the License, or<br>&nbsp;&nbsp;&nbsp; (at your option) any later version.<p>&nbsp;&nbsp;&nbsp; This program is distributed in the hope that it will be useful,<br>&nbsp;&nbsp;&nbsp; but WITHOUT ANY WARRANTY; without even the implied warranty of<br>&nbsp;&nbsp;&nbsp; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.&nbsp; See the<br>&nbsp;&nbsp;&nbsp; GNU General Public License for more details.<p>&nbsp;&nbsp;&nbsp; You should have received a copy of the GNU General Public License<br>&nbsp;&nbsp;&nbsp; along with this program; if not, write to the Free Software<br>&nbsp;&nbsp;&nbsp; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.<br>***********************************************************************/<p>new_thread(int (*start_addr)(void), int stack_size)<br>{<br>&nbsp;&nbsp;&nbsp; struct context *ptr;<br>&nbsp;&nbsp;&nbsp; int esp;<p>&nbsp;&nbsp;&nbsp; /* 1 */<br>&nbsp;&nbsp;&nbsp; if (!(ptr = (struct context *)malloc(sizeof(struct context))))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0;<p>&nbsp;&nbsp;&nbsp; /* 2 */<br>&nbsp;&nbsp;&nbsp; if (!(ptr-&gt;stack = (char *)malloc(stack_size)))<br>&nbsp;&nbsp;&

⌨️ 快捷键说明

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