📄 kernel-thread-control.html
字号:
<!-- Copyright (C) 2003 Red Hat, Inc. --><!-- This material may be distributed only subject to the terms --><!-- and conditions set forth in the Open Publication License, v1.0 --><!-- or later (the latest version is presently available at --><!-- http://www.opencontent.org/openpub/). --><!-- Distribution of the work or derivative of the work in any --><!-- standard (paper) book form is prohibited unless prior --><!-- permission is obtained from the copyright holder. --><HTML><HEAD><TITLE>Thread control</TITLE><meta name="MSSmartTagsPreventParsing" content="TRUE"><METANAME="GENERATOR"CONTENT="Modular DocBook HTML Stylesheet Version 1.76b+"><LINKREL="HOME"TITLE="eCos Reference Manual"HREF="ecos-ref.html"><LINKREL="UP"TITLE="The eCos Kernel"HREF="kernel.html"><LINKREL="PREVIOUS"TITLE="Thread information"HREF="kernel-thread-info.html"><LINKREL="NEXT"TITLE="Thread termination"HREF="kernel-thread-termination.html"></HEAD><BODYCLASS="REFENTRY"BGCOLOR="#FFFFFF"TEXT="#000000"LINK="#0000FF"VLINK="#840084"ALINK="#0000FF"><DIVCLASS="NAVHEADER"><TABLESUMMARY="Header navigation table"WIDTH="100%"BORDER="0"CELLPADDING="0"CELLSPACING="0"><TR><THCOLSPAN="3"ALIGN="center">eCos Reference Manual</TH></TR><TR><TDWIDTH="10%"ALIGN="left"VALIGN="bottom"><AHREF="kernel-thread-info.html"ACCESSKEY="P">Prev</A></TD><TDWIDTH="80%"ALIGN="center"VALIGN="bottom"></TD><TDWIDTH="10%"ALIGN="right"VALIGN="bottom"><AHREF="kernel-thread-termination.html"ACCESSKEY="N">Next</A></TD></TR></TABLE><HRALIGN="LEFT"WIDTH="100%"></DIV><H1><ANAME="KERNEL-THREAD-CONTROL">Thread control</H1><DIVCLASS="REFNAMEDIV"><ANAME="AEN482"></A><H2>Name</H2>cyg_thread_yield, cyg_thread_delay, cyg_thread_suspend, cyg_thread_resume, cyg_thread_release -- Control whether or not a thread is running</DIV><DIVCLASS="REFSYNOPSISDIV"><ANAME="AEN489"><H2>Synopsis</H2><DIVCLASS="FUNCSYNOPSIS"><ANAME="AEN490"><P></P><TABLEBORDER="5"BGCOLOR="#E0E0F0"WIDTH="70%"><TR><TD><PRECLASS="FUNCSYNOPSISINFO">#include <cyg/kernel/kapi.h> </PRE></TD></TR></TABLE><P><CODE><CODECLASS="FUNCDEF">void cyg_thread_yield</CODE>(void);</CODE></P><P><CODE><CODECLASS="FUNCDEF">void cyg_thread_delay</CODE>(cyg_tick_count_t delay);</CODE></P><P><CODE><CODECLASS="FUNCDEF">void cyg_thread_suspend</CODE>(cyg_handle_t thread);</CODE></P><P><CODE><CODECLASS="FUNCDEF">void cyg_thread_resume</CODE>(cyg_handle_t thread);</CODE></P><P><CODE><CODECLASS="FUNCDEF">void cyg_thread_release</CODE>(cyg_handle_t thread);</CODE></P><P></P></DIV></DIV><DIVCLASS="REFSECT1"><ANAME="AEN516"></A><H2>Description</H2><P>These functions provide some control over whether or not a particularthread can run. Apart from the required use of<TTCLASS="FUNCTION">cyg_thread_resume</TT> to start a newly-createdthread, application code should normally use proper synchronizationprimitives such as condition variables or mail boxes. </P></DIV><DIVCLASS="REFSECT1"><ANAME="AEN520"></A><H2>Yield</H2><P><TTCLASS="FUNCTION">cyg_thread_yield</TT> allows a thread to relinquishcontrol of the processor to some other runnable thread which has thesame priority. This can have no effect on any higher-priority threadsince, if such a thread were runnable, the current thread would havebeen preempted in its favour. Similarly it can have no effect on anylower-priority thread because the current thread will always be run inpreference to those. As a consequence this function is only usefulin configurations with a scheduler that allows multiple threads to runat the same priority, for example the mlqueue scheduler. If insteadthe bitmap scheduler was being used then<TTCLASS="FUNCTION">cyg_thread_yield()</TT> would serve no purpose. </P><P>Even if a suitable scheduler such as the mlqueue scheduler has beenconfigured, <TTCLASS="FUNCTION">cyg_thread_yield</TT> will still rarelyprove useful: instead timeslicing will be used to ensure that allthreads of a given priority get a fair slice of the availableprocessor time. However it is possible to disable timeslicing via theconfiguration option <TTCLASS="VARNAME">CYGSEM_KERNEL_SCHED_TIMESLICE</TT>,in which case <TTCLASS="FUNCTION">cyg_thread_yield</TT> can be used toimplement a form of cooperative multitasking. </P></DIV><DIVCLASS="REFSECT1"><ANAME="AEN529"></A><H2>Delay</H2><P><TTCLASS="FUNCTION">cyg_thread_delay</TT> allows a thread to suspend untilthe specified number of clock ticks have occurred. For example, if avalue of 1 is used and the system clock runs at a frequency of 100Hzthen the thread will sleep for up to 10 milliseconds. Thisfunctionality depends on the presence of a real-time system clock, ascontrolled by the configuration option<TTCLASS="VARNAME">CYGVAR_KERNEL_COUNTERS_CLOCK</TT>. </P><P>If the application requires delays measured in milliseconds or similarunits rather than in clock ticks, some calculations are needed toconvert between these units as described in <AHREF="kernel-clocks.html">Clocks</A>. Usually these calculations can be done bythe application developer, or at compile-time. Performing suchcalculations prior to every call to<TTCLASS="FUNCTION">cyg_thread_delay</TT> adds unnecessary overhead to thesystem. </P></DIV><DIVCLASS="REFSECT1"><ANAME="AEN537"></A><H2>Suspend and Resume</H2><P>Associated with each thread is a suspend counter. When a thread isfirst created this counter is initialized to 1.<TTCLASS="FUNCTION">cyg_thread_suspend</TT> can be used to increment thesuspend counter, and <TTCLASS="FUNCTION">cyg_thread_resume</TT> decrementsit. The scheduler will never run a thread with a non-zero suspendcounter. Therefore a newly created thread will not run until it hasbeen resumed. </P><P>An occasional problem with the use of suspend and resume functionalityis that a thread gets suspended more times than it is resumed andhence never becomes runnable again. This can lead to very confusingbehaviour. To help with debugging such problems the kernel provides aconfiguration option<TTCLASS="VARNAME">CYGNUM_KERNEL_MAX_SUSPEND_COUNT_ASSERT</TT> whichimposes an upper bound on the number of suspend calls without matchingresumes, with a reasonable default value. This functionality dependson infrastructure assertions being enabled. </P></DIV><DIVCLASS="REFSECT1"><ANAME="AEN544"></A><H2>Releasing a Blocked Thread</H2><P>When a thread is blocked on a synchronization primitive such as asemaphore or a mutex, or when it is waiting for an alarm to trigger,it can be forcibly woken up using<TTCLASS="FUNCTION">cyg_thread_release</TT>. Typically this will call theaffected synchronization primitive to return false, indicating thatthe operation was not completed successfully. This function has to beused with great care, and in particular it should only be used onthreads that have been designed appropriately and check all returncodes. If instead it were to be used on, say, an arbitrary thread thatis attempting to claim a mutex then that thread might not bother tocheck the result of the mutex lock operation - usually there would beno reason to do so. Therefore the thread will now continue running inthe false belief that it has successfully claimed a mutex lock, andthe resulting behaviour is undefined. If the system has been builtwith assertions enabled then it is possible that an assertion willtrigger when the thread tries to release the mutex it does notactually own. </P><P>The main use of <TTCLASS="FUNCTION">cyg_thread_release</TT> is in thePOSIX compatibility layer, where it is used in the implementation ofper-thread signals and cancellation handlers. </P></DIV><DIVCLASS="REFSECT1"><ANAME="KERNEL-THREAD-CONTROL-CONTEXT"></A><H2>Valid contexts</H2><P><TTCLASS="FUNCTION">cyg_thread_yield</TT> can only be called from threadcontext, A DSR must always run to completion and cannot yield theprocessor to some thread. <TTCLASS="FUNCTION">cyg_thread_suspend</TT>,<TTCLASS="FUNCTION">cyg_thread_resume</TT>, and<TTCLASS="FUNCTION">cyg_thread_release</TT> may be called from thread orDSR context. </P></DIV><DIVCLASS="NAVFOOTER"><HRALIGN="LEFT"WIDTH="100%"><TABLESUMMARY="Footer navigation table"WIDTH="100%"BORDER="0"CELLPADDING="0"CELLSPACING="0"><TR><TDWIDTH="33%"ALIGN="left"VALIGN="top"><AHREF="kernel-thread-info.html"ACCESSKEY="P">Prev</A></TD><TDWIDTH="34%"ALIGN="center"VALIGN="top"><AHREF="ecos-ref.html"ACCESSKEY="H">Home</A></TD><TDWIDTH="33%"ALIGN="right"VALIGN="top"><AHREF="kernel-thread-termination.html"ACCESSKEY="N">Next</A></TD></TR><TR><TDWIDTH="33%"ALIGN="left"VALIGN="top">Thread information</TD><TDWIDTH="34%"ALIGN="center"VALIGN="top"><AHREF="kernel.html"ACCESSKEY="U">Up</A></TD><TDWIDTH="33%"ALIGN="right"VALIGN="top">Thread termination</TD></TR></TABLE></DIV></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -