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

📄 kernel-mutexes.html

📁 有关ecos2。0介绍了实时嵌入式的结构以及线程调度的实现和内存的管理等
💻 HTML
📖 第 1 页 / 共 2 页
字号:
<!-- 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>Mutexes</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="Alarms"HREF="kernel-alarms.html"><LINKREL="NEXT"TITLE="Condition Variables"HREF="kernel-condition-variables.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-alarms.html"ACCESSKEY="P">Prev</A></TD><TDWIDTH="80%"ALIGN="center"VALIGN="bottom"></TD><TDWIDTH="10%"ALIGN="right"VALIGN="bottom"><AHREF="kernel-condition-variables.html"ACCESSKEY="N">Next</A></TD></TR></TABLE><HRALIGN="LEFT"WIDTH="100%"></DIV><H1><ANAME="KERNEL-MUTEXES">Mutexes</H1><DIVCLASS="REFNAMEDIV"><ANAME="AEN1098"></A><H2>Name</H2>cyg_mutex_init, cyg_mutex_destroy, cyg_mutex_lock, cyg_mutex_trylock, cyg_mutex_unlock, cyg_mutex_release, cyg_mutex_set_ceiling, cyg_mutex_set_protocol&nbsp;--&nbsp;Synchronization primitive</DIV><DIVCLASS="REFSYNOPSISDIV"><ANAME="AEN1108"><H2>Synopsis</H2><DIVCLASS="FUNCSYNOPSIS"><ANAME="AEN1109"><P></P><TABLEBORDER="5"BGCOLOR="#E0E0F0"WIDTH="70%"><TR><TD><PRECLASS="FUNCSYNOPSISINFO">#include &lt;cyg/kernel/kapi.h&gt;        </PRE></TD></TR></TABLE><P><CODE><CODECLASS="FUNCDEF">void cyg_mutex_init</CODE>(cyg_mutex_t* mutex);</CODE></P><P><CODE><CODECLASS="FUNCDEF">void cyg_mutex_destroy</CODE>(cyg_mutex_t* mutex);</CODE></P><P><CODE><CODECLASS="FUNCDEF">cyg_bool_t cyg_mutex_lock</CODE>(cyg_mutex_t* mutex);</CODE></P><P><CODE><CODECLASS="FUNCDEF">cyg_bool_t cyg_mutex_trylock</CODE>(cyg_mutex_t* mutex);</CODE></P><P><CODE><CODECLASS="FUNCDEF">void cyg_mutex_unlock</CODE>(cyg_mutex_t* mutex);</CODE></P><P><CODE><CODECLASS="FUNCDEF">void cyg_mutex_release</CODE>(cyg_mutex_t* mutex);</CODE></P><P><CODE><CODECLASS="FUNCDEF">void cyg_mutex_set_ceiling</CODE>(cyg_mutex_t* mutex, cyg_priority_t priority);</CODE></P><P><CODE><CODECLASS="FUNCDEF">void cyg_mutex_set_protocol</CODE>(cyg_mutex_t* mutex, enum cyg_mutex_protocol protocol/);</CODE></P><P></P></DIV></DIV><DIVCLASS="REFSECT1"><ANAME="KERNEL-MUTEXES-DESCRIPTION"></A><H2>Description</H2><P>The purpose of mutexes is to let threads share resources safely. Iftwo or more threads attempt to manipulate a data structure with nolocking between them then the system may run for quite some timewithout apparent problems, but sooner or later the data structure willbecome inconsistent and the application will start behaving strangelyand is quite likely to crash. The same can apply even whenmanipulating a single variable or some other resource. For example,consider:      </P><TABLEBORDER="5"BGCOLOR="#E0E0F0"WIDTH="70%"><TR><TD><PRECLASS="PROGRAMLISTING">static volatile int counter = 0;voidprocess_event(void){    &#8230;    counter++;}</PRE></TD></TR></TABLE><P>Assume that after a certain period of time <TTCLASS="VARNAME">counter</TT>has a value of 42, and two threads A and B running at the samepriority call <TTCLASS="FUNCTION">process_event</TT>. Typically thread Awill read the value of <TTCLASS="VARNAME">counter</TT> into a register,increment this register to 43, and write this updated value back tomemory. Thread B will do the same, so usually<TTCLASS="VARNAME">counter</TT> will end up with a value of 44. However ifthread A is timesliced after reading the old value 42 but beforewriting back 43, thread B will still read back the old value and willalso write back 43. The net result is that the counter only getsincremented once, not twice, which depending on the application mayprove disastrous.      </P><P>Sections of code like the above which involve manipulating shared dataare generally known as critical regions. Code should claim a lockbefore entering a critical region and release the lock when leaving.Mutexes provide an appropriate synchronization primitive for this.      </P><TABLEBORDER="5"BGCOLOR="#E0E0F0"WIDTH="70%"><TR><TD><PRECLASS="PROGRAMLISTING">static volatile int counter = 0;static cyg_mutex_t  lock;voidprocess_event(void){    &#8230;    cyg_mutex_lock(&amp;lock);    counter++;    cyg_mutex_unlock(&amp;lock);}      </PRE></TD></TR></TABLE><P>A mutex must be initialized before it can be used, by calling<TTCLASS="FUNCTION">cyg_mutex_init</TT>. This takes a pointer to a<SPANCLASS="STRUCTNAME">cyg_mutex_t</SPAN> data structure which is typicallystatically allocated, and may be part of a larger data structure. If amutex is no longer required and there are no threads waiting on itthen <TTCLASS="FUNCTION">cyg_mutex_destroy</TT> can be used.      </P><P>The main functions for using a mutex are<TTCLASS="FUNCTION">cyg_mutex_lock</TT> and<TTCLASS="FUNCTION">cyg_mutex_unlock</TT>. In normal operation<TTCLASS="FUNCTION">cyg_mutex_lock</TT> will return success after claimingthe mutex lock, blocking if another thread currently owns the mutex.However the lock operation may fail if other code calls<TTCLASS="FUNCTION">cyg_mutex_release</TT> or<TTCLASS="FUNCTION">cyg_thread_release</TT>, so if these functions may getused then it is important to check the return value. The current ownerof a mutex should call <TTCLASS="FUNCTION">cyg_mutex_unlock</TT> when alock is no longer required. This operation must be performed by theowner, not by another thread.      </P><P><TTCLASS="FUNCTION">cyg_mutex_trylock</TT> is a variant of<TTCLASS="FUNCTION">cyg_mutex_lock</TT> that will always returnimmediately, returning success or failure as appropriate. Thisfunction is rarely useful. Typical code locks a mutex just beforeentering a critical region, so if the lock cannot be claimed thenthere may be nothing else for the current thread to do. Use of thisfunction may also cause a form of priority inversion if the ownerowner runs at a lower priority, because the priority inheritance codewill not be triggered. Instead the current thread continues running,preventing the owner from getting any cpu time, completing thecritical region, and releasing the mutex.      </P><P><TTCLASS="FUNCTION">cyg_mutex_release</TT> can be used to wake up allthreads that are currently blocked inside a call to<TTCLASS="FUNCTION">cyg_mutex_lock</TT> for a specific mutex. These lockcalls will return failure. The current mutex owner is not affected.      </P></DIV><DIVCLASS="REFSECT1"><ANAME="KERNEL-MUTEXES-PRIORITY-INVERSION"></A><H2>Priority Inversion</H2><P>The use of mutexes gives rise to a problem known as priorityinversion. In a typical scenario this requires three threads A, B, andC, running at high, medium and low priority respectively. Thread A andthread B are temporarily blocked waiting for some event, so thread Cgets a chance to run, needs to enter a critical region, and locksa mutex. At this point threads A and B are woken up - the exact orderdoes not matter. Thread A needs to claim the same mutex but has towait until C has left the critical region and can release the mutex.Meanwhile thread B works on something completely different and cancontinue running without problems. Because thread C is running a lowerpriority than B it will not get a chance to run until B blocks forsome reason, and hence thread A cannot run either. The overall effectis that a high-priority thread A cannot proceed because of a lowerpriority thread B, and priority inversion has occurred.      </P><P>In simple applications it may be possible to arrange the code suchthat priority inversion cannot occur, for example by ensuring that agiven mutex is never shared by threads running at different priority

⌨️ 快捷键说明

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