📄 a00015.html
字号:
main(<span class="keywordtype">void</span>){ <span class="comment">/*</span><span class="comment"> * Initialize the two protothread control structures.</span><span class="comment"> */</span> <a class="code" href="a00014.html#ge6bae7dc0225468c8a5ac269df549892">PT_INIT</a>(&input_pt); <a class="code" href="a00014.html#ge6bae7dc0225468c8a5ac269df549892">PT_INIT</a>(&codelock_pt); <span class="comment">/*</span><span class="comment"> * Schedule the two protothreads until the codelock_thread() exits.</span><span class="comment"> */</span> <span class="keywordflow">while</span>(<a class="code" href="a00014.html#gfa82b860a64b67d25ab3abc21811896f">PT_SCHEDULE</a>(codelock_thread(&codelock_pt))) { <a class="code" href="a00014.html#gfa82b860a64b67d25ab3abc21811896f">PT_SCHEDULE</a>(input_thread(&input_pt)); <span class="comment">/*</span><span class="comment"> * When running this example on a multitasking system, we must</span><span class="comment"> * give other processes a chance to run too and therefore we call</span><span class="comment"> * usleep() resp. Sleep() here. On a dedicated embedded system,</span><span class="comment"> * we usually do not need to do this.</span><span class="comment"> */</span><span class="preprocessor">#ifdef _WIN32</span><span class="preprocessor"></span> Sleep(0);<span class="preprocessor">#else</span><span class="preprocessor"></span> usleep(10);<span class="preprocessor">#endif</span><span class="preprocessor"></span> } <span class="keywordflow">return</span> 0;}<span class="comment">/*---------------------------------------------------------------------------*/</span><span class="comment">/*</span><span class="comment"> * Finally, the implementation of the simple timer library follows.</span><span class="comment"> */</span><span class="preprocessor">#ifdef _WIN32</span><span class="preprocessor"></span><span class="keyword">static</span> <span class="keywordtype">int</span> clock_time(<span class="keywordtype">void</span>){ <span class="keywordflow">return</span> (<span class="keywordtype">int</span>)GetTickCount(); }<span class="preprocessor">#else </span><span class="comment">/* _WIN32 */</span><span class="keyword">static</span> <span class="keywordtype">int</span> clock_time(<span class="keywordtype">void</span>){ <span class="keyword">struct </span>timeval tv; <span class="keyword">struct </span>timezone tz; gettimeofday(&tv, &tz); <span class="keywordflow">return</span> tv.tv_sec * 1000 + tv.tv_usec / 1000;}<span class="preprocessor">#endif </span><span class="comment">/* _WIN32 */</span><span class="keyword">static</span> <span class="keywordtype">int</span> timer_expired(<span class="keyword">struct</span> timer *t){ <span class="keywordflow">return</span> (<span class="keywordtype">int</span>)(clock_time() - t->start) >= (<span class="keywordtype">int</span>)t->interval; }<span class="keyword">static</span> <span class="keywordtype">void</span> timer_set(<span class="keyword">struct</span> timer *t, <span class="keywordtype">int</span> interval){ t->interval = interval; t->start = clock_time(); }<span class="comment">/*---------------------------------------------------------------------------*/</span></pre></div><h2><a class="anchor" name="example-buffer">The bounded buffer with protothread semaphores</a></h2>The following example shows how to implement the bounded buffer problem using the protothreads semaphore library. The example uses three protothreads: one producer() protothread that produces items, one consumer() protothread that consumes items, and one driver_thread() that schedules the producer and consumer protothreads.<p>Note that there is no need for a mutex to guard the add_to_buffer() and get_from_buffer() functions because of the implicit locking semantics of protothreads - a protothread will never be preempted and will never block except in an explicit PT_WAIT statement.<p><div class="fragment"><pre class="fragment"><span class="comment">/*</span><span class="comment"> * Copyright (c) 2004-2005, Swedish Institute of Computer Science.</span><span class="comment"> * All rights reserved. </span><span class="comment"> *</span><span class="comment"> * Redistribution and use in source and binary forms, with or without </span><span class="comment"> * modification, are permitted provided that the following conditions </span><span class="comment"> * are met: </span><span class="comment"> * 1. Redistributions of source code must retain the above copyright </span><span class="comment"> * notice, this list of conditions and the following disclaimer. </span><span class="comment"> * 2. Redistributions in binary form must reproduce the above copyright </span><span class="comment"> * notice, this list of conditions and the following disclaimer in the </span><span class="comment"> * documentation and/or other materials provided with the distribution. </span><span class="comment"> * 3. Neither the name of the Institute nor the names of its contributors </span><span class="comment"> * may be used to endorse or promote products derived from this software </span><span class="comment"> * without specific prior written permission. </span><span class="comment"> *</span><span class="comment"> * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND </span><span class="comment"> * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE </span><span class="comment"> * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE </span><span class="comment"> * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE </span><span class="comment"> * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL </span><span class="comment"> * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS </span><span class="comment"> * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) </span><span class="comment"> * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT </span><span class="comment"> * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY </span><span class="comment"> * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF </span><span class="comment"> * SUCH DAMAGE. </span><span class="comment"> *</span><span class="comment"> * This file is part of the protothreads library.</span><span class="comment"> *</span><span class="comment"> * Author: Adam Dunkels <adam@sics.se></span><span class="comment"> *</span><span class="comment"> * $Id: example-buffer.c,v 1.5 2005/10/07 05:21:33 adam Exp $</span><span class="comment"> */</span><span class="preprocessor">#ifdef _WIN32</span><span class="preprocessor"></span><span class="preprocessor">#include <windows.h></span><span class="preprocessor">#else</span><span class="preprocessor"></span><span class="preprocessor">#include <unistd.h></span><span class="preprocessor">#endif</span><span class="preprocessor"></span><span class="preprocessor">#include <stdio.h></span><span class="preprocessor">#include "<a class="code" href="a00012.html">pt-sem.h</a>"</span> <span class="preprocessor">#define NUM_ITEMS 32</span><span class="preprocessor"></span><span class="preprocessor">#define BUFSIZE 8</span><span class="preprocessor"></span><span class="keyword">static</span> <span class="keywordtype">int</span> buffer[BUFSIZE];<span class="keyword">static</span> <span class="keywordtype">int</span> bufptr;<span class="keyword">static</span> <span class="keywordtype">void</span>add_to_buffer(<span class="keywordtype">int</span> item){ printf(<span class="stringliteral">"Item %d added to buffer at place %d\n"</span>, item, bufptr); buffer[bufptr] = item; bufptr = (bufptr + 1) % BUFSIZE;}<span class="keyword">static</span> <span class="keywordtype">int</span>get_from_buffer(<span class="keywordtype">void</span>){ <span class="keywordtype">int</span> item; item = buffer[bufptr]; printf(<span class="stringliteral">"Item %d retrieved from buffer at place %d\n"</span>, item, bufptr); bufptr = (bufptr + 1) % BUFSIZE; <span class="keywordflow">return</span> item;}<span class="keyword">static</span> <span class="keywordtype">int</span>produce_item(<span class="keywordtype">void</span>){ <span class="keyword">static</span> <span class="keywordtype">int</span> item = 0; printf(<span class="stringliteral">"Item %d produced\n"</span>, item); <span class="keywordflow">return</span> item++;}<span class="keyword">static</span> <span class="keywordtype">void</span>consume_item(<span class="keywordtype">int</span> item){ printf(<span class="stringliteral">"Item %d consumed\n"</span>, item);}<span class="keyword">static</span> <span class="keyword">struct </span><a class="code" href="a00006.html">pt_sem</a> full, empty; <span class="keyword">static</span> <a class="code" href="a00014.html#g3d4c8bd4aada659eb34f5d2ffd3e7901">PT_THREAD</a>(producer(<span class="keyword">struct</span> pt *pt)){ <span class="keyword">static</span> <span class="keywordtype">int</span> produced; <a class="code" href="a00014.html#g2ffbb9e554e08a343ae2f9de4bedfdfc">PT_BEGIN</a>(pt); <span class="keywordflow">for</span>(produced = 0; produced < NUM_ITEMS; ++produced) { <a class="code" href="a00016.html#g386ff87a52a840512906f2940e229e2e">PT_SEM_WAIT</a>(pt, &full); add_to_buffer(produce_item()); <a class="code" href="a00016.html#g1eaaf4d9d75e24582acc6440d7085f19">PT_SEM_SIGNAL</a>(pt, &empty); } <a class="code" href="a00014.html#g7b04a0035bef29d905496c23bae066d2">PT_END</a>(pt);} <span class="keyword">static</span> <a class="code" href="a00014.html#g3d4c8bd4aada659eb34f5d2ffd3e7901">PT_THREAD</a>(consumer(<span class="keyword">struct</span> pt *pt)){ <span class="keyword">static</span> <span class="keywordtype">int</span> consumed; <a class="code" href="a00014.html#g2ffbb9e554e08a343ae2f9de4bedfdfc">PT_BEGIN</a>(pt); <span class="keywordflow">for</span>(consumed = 0; consumed < NUM_ITEMS; ++consumed) { <a class="code" href="a00016.html#g386ff87a52a840512906f2940e229e2e">PT_SEM_WAIT</a>(pt, &empty); consume_item(get_from_buffer()); <a class="code" href="a00016.html#g1eaaf4d9d75e24582acc6440d7085f19">PT_SEM_SIGNAL</a>(pt, &full); } <a class="code" href="a00014.html#g7b04a0035bef29d905496c23bae066d2">PT_END</a>(pt);} <span class="keyword">static</span> <a class="code" href="a00014.html#g3d4c8bd4aada659eb34f5d2ffd3e7901">PT_THREAD</a>(driver_thread(<span class="keyword">struct</span> pt *pt)){ <span class="keyword">static</span> <span class="keyword">struct </span>pt pt_producer, pt_consumer; <a class="code" href="a00014.html#g2ffbb9e554e08a343ae2f9de4bedfdfc">PT_BEGIN</a>(pt); <a class="code" href="a00016.html#gd7089c5dc86f12019f0361d82a75b04b">PT_SEM_INIT</a>(&empty, 0); <a class="code" href="a00016.html#gd7089c5dc86f12019f0361d82a75b04b">PT_SEM_INIT</a>(&full, BUFSIZE); <a class="code" href="a00014.html#ge6bae7dc0225468c8a5ac269df549892">PT_INIT</a>(&pt_producer); <a class="code" href="a00014.html#ge6bae7dc0225468c8a5ac269df549892">PT_INIT</a>(&pt_consumer); <a class="code" href="a00014.html#g2f8f70c30b9ee08a103fbd69a4365c4c">PT_WAIT_THREAD</a>(pt, producer(&pt_producer) & consumer(&pt_consumer)); <a class="code" href="a00014.html#g7b04a0035bef29d905496c23bae066d2">PT_END</a>(pt);}<span class="keywordtype">int</span>main(<span class="keywordtype">void</span>){ <span class="keyword">struct </span>pt driver_pt; <a class="code" href="a00014.html#ge6bae7dc0225468c8a5ac269df549892">PT_INIT</a>(&driver_pt); <span class="keywordflow">while</span>(<a class="code" href="a00014.html#gfa82b860a64b67d25ab3abc21811896f">PT_SCHEDULE</a>(driver_thread(&driver_pt))) { <span class="comment">/*</span><span class="comment"> * When running this example on a multitasking system, we must</span><span class="comment"> * give other processes a chance to run too and therefore we call</span><span class="comment"> * usleep() resp. Sleep() here. On a dedicated embedded system,</span><span class="comment"> * we usually do not need to do this.</span><span class="comment"> */</span><span class="preprocessor">#ifdef _WIN32</span><span class="preprocessor"></span> Sleep(0);<span class="preprocessor">#else</span><span class="preprocessor"></span> usleep(10);<span class="preprocessor">#endif</span><span class="preprocessor"></span> } <span class="keywordflow">return</span> 0;}</pre></div> <p><table border="0" cellpadding="0" cellspacing="0"><tr><td></td></tr></table><hr size="1"><address style="align: right;"><small>Generated on Mon Oct 2 10:06:29 2006 for The Protothreads Library 1.4 by <a href="http://www.doxygen.org/index.html"><img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.4.6 </small></address></body></html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -