1 <!-- Copyright (C) 2003 Red Hat, Inc. -->
2 <!-- This material may be distributed only subject to the terms -->
3 <!-- and conditions set forth in the Open Publication License, v1.0 -->
4 <!-- or later (the latest version is presently available at -->
5 <!-- http://www.opencontent.org/openpub/). -->
6 <!-- Distribution of the work or derivative of the work in any -->
7 <!-- standard (paper) book form is prohibited unless prior -->
8 <!-- permission is obtained from the copyright holder. -->
12 >A Sample Program with Two Threads</TITLE
13 ><meta name="MSSmartTagsPreventParsing" content="TRUE">
16 CONTENT="Modular DocBook HTML Stylesheet Version 1.76b+
19 TITLE="eCos User Guide"
20 HREF="ecos-user-guide.html"><LINK
22 TITLE="Building and Running Sample Applications"
23 HREF="building-and-running-sample-appliations.html"><LINK
25 TITLE="Building and Running Sample Applications"
26 HREF="building-and-running-sample-appliations.html"><LINK
28 TITLE="More Features — Clocks and Alarm
30 HREF="clocks-and-alarm-handlers.html"></HEAD
41 SUMMARY="Header navigation table"
58 HREF="building-and-running-sample-appliations.html"
66 >Chapter 13. Building and Running Sample Applications</TD
72 HREF="clocks-and-alarm-handlers.html"
86 NAME="SAMPLE-TWOTHREADS">A Sample Program with Two Threads</H1
88 >Below is a program that uses some of <SPAN
92 creates two threads, each of which goes into an infinite loop in which
93 it sleeps for a while (using cyg_thread_delay()). This code is found
98 in the examples directory.</P
107 > two-threaded program listing</H2
115 CLASS="PROGRAMLISTING"
116 >#include <cyg/kernel/kapi.h>
117 #include <stdio.h>
118 #include <math.h>
119 #include <stdlib.h>
121 /* now declare (and allocate space for) some kernel objects,
122 like the two threads we will use */
123 cyg_thread thread_s[2]; /* space for two thread objects */
125 char stack[2][4096]; /* space for two 4K stacks */
127 /* now the handles for the threads */
128 cyg_handle_t simple_threadA, simple_threadB;
130 /* and now variables for the procedure which is the thread */
131 cyg_thread_entry_t simple_program;
133 /* and now a mutex to protect calls to the C library */
134 cyg_mutex_t cliblock;
136 /* we install our own startup routine which sets up threads */
137 void cyg_user_start(void)
139 printf("Entering twothreads' cyg_user_start() function\n");
141 cyg_mutex_init(&cliblock);
143 cyg_thread_create(4, simple_program, (cyg_addrword_t) 0,
144 "Thread A", (void *) stack[0], 4096,
145 &simple_threadA, &thread_s[0]);
146 cyg_thread_create(4, simple_program, (cyg_addrword_t) 1,
147 "Thread B", (void *) stack[1], 4096,
148 &simple_threadB, &thread_s[1]);
150 cyg_thread_resume(simple_threadA);
151 cyg_thread_resume(simple_threadB);
154 /* this is a simple program which runs in a thread */
155 void simple_program(cyg_addrword_t data)
157 int message = (int) data;
160 printf("Beginning execution; thread data is %d\n", message);
162 cyg_thread_delay(200);
165 delay = 200 + (rand() % 50);
167 /* note: printf() must be protected by a
168 call to cyg_mutex_lock() */
169 cyg_mutex_lock(&cliblock); {
170 printf("Thread %d: and now a delay of %d clock ticks\n",
173 cyg_mutex_unlock(&cliblock);
174 cyg_thread_delay(delay);
181 >When you run the program (by typing <B
191 >) prompt) the output should look like
200 CLASS="PROGRAMLISTING"
201 >Starting program: <TT
206 >/examples/twothreads.exe
207 Entering twothreads' cyg_user_start()
209 Beginning execution; thread data is 0
210 Beginning execution; thread data is 1
211 Thread 0: and now a delay of 240 clock ticks
212 Thread 1: and now a delay of 225 clock ticks
213 Thread 1: and now a delay of 234 clock ticks
214 Thread 0: and now a delay of 231 clock ticks
215 Thread 1: and now a delay of 224 clock ticks
216 Thread 0: and now a delay of 249 clock ticks
217 Thread 1: and now a delay of 202 clock ticks
218 Thread 0: and now a delay of 235 clock ticks</PRE
229 >When running in a simulator the
230 delays might be quite long. On a hardware board (where the clock
231 speed is 100 ticks/second) the delays should average to
232 about 2.25 seconds. In simulation, the delay will depend on the
233 speed of the host processor and will almost always be much slower than
234 the actual board. You might want to reduce the delay parameter when running
240 HREF="sample-twothreads.html#FIGURE-TWOTHREADS-WITH-SIMPLE-PRINTS"
243 multitasking program executes. Note that apart from the thread
244 creation system calls, this program also creates and uses a
251 > for synchronization
256 threads. This is because the C library standard I/O (by default) is
257 configured not to be thread-safe, which means that if more than one
258 thread is using standard I/O they might corrupt each other. This is
259 fixed by a mutual exclusion (or <SPAN
266 mechanism: the threads do not call <TT
272 >cyg_mutex_lock()</TT
273 > has returned, which only happens
274 when the other thread calls
277 >cyg_mutex_unlock()</TT
280 >You could avoid using the mutex by configuring the C library to
281 be thread-safe (by selecting the component
284 >CYGSEM_LIBC_STDIO_THREAD_SAFE_STREAMS</TT
289 NAME="FIGURE-TWOTHREADS-WITH-SIMPLE-PRINTS"><P
292 threads with simple print statements after random delays</B
296 SRC="pix/twothreads2.png"></P
305 SUMMARY="Footer navigation table"
316 HREF="building-and-running-sample-appliations.html"
325 HREF="ecos-user-guide.html"
334 HREF="clocks-and-alarm-handlers.html"
344 >Building and Running Sample Applications</TD
350 HREF="building-and-running-sample-appliations.html"
358 >More Features — Clocks and Alarm