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

📄 posix threads programming.htm

📁 可以自学操作系统全部课程
💻 HTM
📖 第 1 页 / 共 5 页
字号:
  <LI>The <TT>pthread_detach()</TT> routine can be used to explicitly detach a 
  thread even though it was created as joinable. There is no converse routine. 
  <P></P>
  <LI>The final draft of the POSIX standard specifies that threads should be 
  created as joinable. However, not all implementations may follow this. 
  <P></P>
  <LI>Recommendations: 
  <UL>
    <LI>If a thread requires joining, consider explicitly creating it as 
    joinable. This provides portability as not all implementations may create 
    threads as joinable by default. 
    <LI>If you know in advance that a thread will never need to join with 
    another thread, consider creating it in a detached state. Some system 
    resources may be able to be freed. </LI></UL></LI></UL><!---------------------------------------------------------------------------><A 
name=JoiningExample><BR><BR></A>
<TABLE cellSpacing=0 cellPadding=5 width="100%" border=1>
  <TBODY>
  <TR>
    <TD background="POSIX Threads Programming.files/bg2.gif" 
      bgColor=navy><SPAN class=heading1>Thread Management 
  </SPAN></TD></TD></TR></TBODY></TABLE>
<P><SPAN class=heading2>Example: Pthread Joining </SPAN>
<P><BR>
<UL>
  <P>
  <TABLE cellSpacing=0 cellPadding=5 width="90%" border=1>
    <TBODY>
    <TR>
      <TD bgColor=#eeeeee><IMG height=22 
        src="POSIX Threads Programming.files/page01.gif" width=20 align=top> 
        <B><SPAN class=heading3>Example Code - Pthread Joining</SPAN></B> 
        <UL>This example demonstrates how to "wait" for thread completions by 
          using the Pthread join routine. Since not all current implementations 
          of Pthreads create threads in a joinable state, the threads in this 
          example are explicitly created in a joinable state so that they can be 
          joined later. </UL>
        <HR>
        <FONT size=-1><PRE><B>
<FONT color=red>#include &lt;pthread.h&gt;</FONT>
#include &lt;stdio.h&gt;
#define NUM_THREADS	3

void *BusyWork(void *null)
{
   int i;
   double result=0.0;
   for (i=0; i &lt; 1000000; i++)
   {
     result = result + (double)random();
   }
   printf("result = %e\n",result);
   <FONT color=red>pthread_exit((void *) 0);</FONT>
}

int main (int argc, char *argv[])
{
   <FONT color=red>pthread_t thread[NUM_THREADS];</FONT>
   <FONT color=red>pthread_attr_t attr;</FONT>
   int rc, t, status;

   /* Initialize and set thread detached attribute */
   <FONT color=red>pthread_attr_init(&amp;attr);</FONT>
   <FONT color=red>pthread_attr_setdetachstate(&amp;attr, PTHREAD_CREATE_JOINABLE);</FONT>

   for(t=0;t &lt; NUM_THREADS;t++)
   {
      printf("Creating thread %d\n", t);
      <FONT color=red>rc = pthread_create(&amp;thread[t], &amp;attr, BusyWork, NULL); </FONT>
      if (rc)
      {
         printf("ERROR; return code from pthread_create() 
                is %d\n", rc);
         exit(-1);
      }
   }

   /* Free attribute and wait for the other threads */
   <FONT color=red>pthread_attr_destroy(&amp;attr);</FONT>
   for(t=0;t &lt; NUM_THREADS;t++)
   {
      <FONT color=red> rc = pthread_join(thread[t], (void **)&amp;status);</FONT>
      if (rc)
      {
         printf("ERROR; return code from pthread_join() 
                is %d\n", rc);
         exit(-1);
      }
      printf("Completed join with thread %d status= %d\n",t, status);
   }

   <FONT color=red>pthread_exit(NULL);</FONT>
}
</B></PRE><A onclick=blur() 
        href="http://www.llnl.gov/computing/tutorials/workshops/workshop/pthreads/samples/join1.c" 
        target=W2><IMG height=20 alt="View source code" 
        src="POSIX Threads Programming.files/source1.gif" width=65 border=0></A> 
        <A onclick=blur() 
        href="http://www.llnl.gov/computing/tutorials/workshops/workshop/pthreads/samples/join1.out" 
        target=W2><IMG height=20 alt="View sample output" 
        src="POSIX Threads Programming.files/output1.gif" width=65 border=0></A> 
        </FONT></TD></TR></TBODY></TABLE></P></UL><!---------------------------------------------------------------------------><A 
name=Mutexes><BR><BR></A><A name=MutexOverview></A>
<TABLE cellSpacing=0 cellPadding=5 width="100%" border=1>
  <TBODY>
  <TR>
    <TD background="POSIX Threads Programming.files/bg2.gif" 
      bgColor=navy><SPAN class=heading1>Mutex Variables 
  </SPAN></TD></TD></TR></TBODY></TABLE>
<P><SPAN class=heading2>Overview </SPAN>
<P><BR>
<UL>
  <P>
  <LI>Mutex is an abbreviation for "mutual exclusion". Mutex variables are one 
  of the primary means of implementing thread synchronization and for protecting 
  shared data when multiple writes occur. 
  <P></P>
  <LI>A mutex variable acts like a "lock" protecting access to a shared data 
  resource. The basic concept of a mutex as used in Pthreads is that only one 
  thread can lock (or own) a mutex variable at any given time. Thus, even if 
  several threads try to lock a mutex only one thread will be successful. No 
  other thread can own that mutex until the owning thread unlocks that mutex. 
  Threads must "take turns" accessing protected data. 
  <P></P>
  <LI>Mutexes can be used to prevent "race" conditions. An example of a race 
  condition involving a bank transaction is shown below: 
  <P>
  <TABLE cellSpacing=0 cellPadding=5 width="90%" border=1>
    <TBODY>
    <TR>
      <TH bgColor=#eeeeee><SPAN class=heading3>Thread 1</SPAN></TH>
      <TH bgColor=#eeeeee><SPAN class=heading3>Thread 2</SPAN></TH>
      <TH bgColor=#eeeeee><SPAN class=heading3>Balance</SPAN></TH></TR>
    <TR>
      <TD>Read balance: $1000</TD>
      <TD>&nbsp;</TD>
      <TD>$1000</TD></TR>
    <TR>
      <TD>&nbsp;</TD>
      <TD>Read balance: $1000</TD>
      <TD>$1000</TD></TR>
    <TR>
      <TD>&nbsp;</TD>
      <TD>Deposit $200</TD>
      <TD>$1000</TD></TR>
    <TR>
      <TD>Deposit $200</TD>
      <TD>&nbsp;</TD>
      <TD>$1000</TD></TR>
    <TR>
      <TD>Update balance $1000+$200</TD>
      <TD>&nbsp;</TD>
      <TD>$1200</TD></TR>
    <TR>
      <TD>&nbsp;</TD>
      <TD>Update balance $1000+$200</TD>
      <TD>$1200</TD></TR></TD></TBODY></TABLE>
  <P></P>
  <LI>In the above example, a mutex should be used to lock the "Balance" while a 
  thread is using this shared data resource. 
  <P></P>
  <LI>Very often the action performed by a thread owning a mutex is the updating 
  of global variables. This is a safe way to ensure that when several threads 
  update the same variable, the final value is the same as what it would be if 
  only one thread performed the update. The variables being updated belong to a 
  "critical section". 
  <P></P>
  <LI>A typical sequence in the use of a mutex is as follows: 
  <UL>
    <LI>Create and initialize a mutex variable 
    <LI>Several threads attempt to lock the mutex 
    <LI>Only one succeeds and that thread owns the mutex 
    <LI>The owner thread performs some set of actions 
    <LI>The owner unlocks the mutex 
    <LI>Another thread acquires the mutex and repeats the process 
    <LI>Finally the mutex is destroyed </LI></UL>
  <P></P>
  <LI>When several threads compete for a mutex, the losers block at that call - 
  an unblocking call is available with "trylock" instead of the "lock" call. 
  <P></P>
  <LI>When protecting shared data, it is the programmer's responsibility to make 
  sure every thread that needs to use a mutex does so. For example, if 4 threads 
  are updating the same data, but only one uses a mutex, the data can still be 
  corrupted. </LI></UL><!---------------------------------------------------------------------------><A 
name=MutexCreation><BR><BR></A>
<TABLE cellSpacing=0 cellPadding=5 width="100%" border=1>
  <TBODY>
  <TR>
    <TD background="POSIX Threads Programming.files/bg2.gif" 
      bgColor=navy><SPAN class=heading1>Mutex Variables 
  </SPAN></TD></TD></TR></TBODY></TABLE>
<P><SPAN class=heading2>Creating / Destroying Mutexes </SPAN>
<P><BR>
<UL>
  <P>
  <LI>Routines: 
  <P>
  <TABLE cellSpacing=0 cellPadding=5 width="90%" border=1>
    <TBODY>
    <TR>
      <TD bgColor=#eeeeee><TT><B><A onclick=blur() 
        href="http://www.llnl.gov/computing/tutorials/workshops/workshop/pthreads/man/pthread_mutex_init.html" 
        target=W2>pthread_mutex_init</A> (mutex,attr) 
        <P><A onclick=blur() 
        href="http://www.llnl.gov/computing/tutorials/workshops/workshop/pthreads/man/pthread_mutex_destroy.html" 
        target=W2>pthread_mutex_destroy</A> (mutex) 
        <P><A onclick=blur() 
        href="http://www.llnl.gov/computing/tutorials/workshops/workshop/pthreads/man/pthread_mutexattr_init.html" 
        target=W2>pthread_mutexattr_init</A> (attr) 
        <P><A onclick=blur() 
        href="http://www.llnl.gov/computing/tutorials/workshops/workshop/pthreads/man/pthread_mutexattr_destroy.html" 
        target=W2>pthread_mutexattr_destroy</A> (attr) 
    </P></B></TT></TD></TR></TBODY></TABLE>
  <P></P>
  <LI>Mutex variables must be declared with type <TT>pthread_mutex_t</TT>, and 
  must be initialized before they can be used. There are two ways to initialize 
  a mutex variable: 
  <OL>
    <P>
    <LI>Statically, when it is declared. For example: <BR><TT>pthread_mutex_t 
    mymutex = PTHREAD_MUTEX_INITIALIZER;</TT> 
    <P></P>
    <LI>Dynamically, with the <TT>pthread_mutex_init()</TT> routine. This method 
    permits setting mutex object attributes, <I>attr</I>. </LI></OL>
  <P>The mutex is initially unlocked. 
  <P></P>
  <LI>The <I>attr</I> object is used to establish properties for the mutex 
  object, and must be of type <TT>pthread_mutexattr_t</TT> if used (may be 
  specified as NULL to accept defaults). The Pthreads standard defines three 
  optional mutex attributes: 
  <UL>
    <LI>Protocol: Specifies the protocol used to prevent priority inversions for 
    a mutex. 
    <LI>Prioceiling: Specifies the priority ceiling of a mutex. 
    <LI>Process-shared: Specifies the process sharing of a mutex. </LI></UL>
  <P>Note that not all implementations may provide the three optional mutex 
  attributes. 
  <P></P>
  <LI>The <TT>pthread_mutexattr_init()</TT> and 
  <TT>pthread_mutexattr_destroy()</TT> routines are used to create and destroy 
  mutex attribute objects respectively. 
  <P></P>
  <LI><TT>pthread_mutex_destroy()</TT> should be used to free a mutex object 
  which is no longer needed. </LI></UL><!---------------------------------------------------------------------------><A 
name=MutexLocking><BR><BR></A>
<TABLE cellSpacing=0 cellPadding=5 width="100%" border=1>
  <TBODY>
  <TR>
    <TD background="POSIX Threads Programming.files/bg2.gif" 
      bgColor=navy><SPAN class=heading1>Mutex Variables 
  </SPAN></TD></TD></TR></TBODY></TABLE>
<P><SPAN class=heading2>Locking / Unlocking Mutexes </SPAN>
<P><BR>
<UL>
  <P>
  <LI>Routines: 
  <P>
  <TABLE cellSpacing=0 cellPadding=5 width="90%" border=1>
    <TBODY>
    <TR>
      <TD bgColor=#eeeeee><TT><B><A onclick=blur() 
        href="http://www.llnl.gov/computing/tutorials/workshops/workshop/pthreads/man/pthread_mutex_lock.html" 
        target=W2>pthread_mutex_lock</A> (mutex) 
        <P><A onclick=blur() 
        href="http://www.llnl.gov/computing/tutorials/workshops/workshop/pthreads/man/pthread_mutex_trylock.html" 
        target=W2>pthread_mutex_trylock</A> (mutex) 
        <P><A onclick=blur() 
        href="http://www.llnl.gov/computing/tutorials/workshops/workshop/pthreads/man/pthread_mutex_unlock.html" 
        target=W2>pthread_mutex_unlock</A> (mutex) 
  </P></B></TT></TD></TR></TBODY></TABLE>
  <P></P>
  <LI>The <TT>pthread_mutex_lock()</TT> routine is used by a thread to acquire a 
  lock on the specified <I>mutex</I> variable. If the mutex is already locked by 
  another thread, this call will block the calling thread until the mutex is 
  unlocked. 
  <P></P>
  <LI><TT>pthread_mutex_trylock()</TT> will attempt to lock a mutex. However, if 
  the mutex is already locked, the routine will return immediately with a "busy" 
  error code. This routine may be useful in preventing deadlock conditions, as 
  in a priority-inversion situation. 
  <P></P>
  <LI><TT>pthread_mutex_unlock()</TT> will unlock a mutex if called by the 
  owning thread. Calling this routine is required after a thread has completed 
  its use of protected data if other threads are to acquire the mutex for their 
  work with the protected data. An error will be returned if: 
  <UL>
    <LI>If the mutex was already unlocked 
    <LI>If the mutex is owned by another thread </LI></UL>
  <P></P>
  <LI>There is nothing "magical" about mutexes...in fact they are akin to a 
  "gentlemen's agreement" between participating threads. It is up to the code 
  writer to insure that the necessary threads all make the the mutex lock and 
  unlock calls correctly. The following scenario demonstrates a logical error: <PRE>    <B>Thread 1     Thread 2     Thread 3</B>
    Lock         Lock         

⌨️ 快捷键说明

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