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

📄 posix threads programming.htm

📁 可以自学操作系统全部课程
💻 HTM
📖 第 1 页 / 共 5 页
字号:
    A = 2        A = A+1      A = A*B
    Unlock       Unlock    
</PRE></LI></UL>
<TABLE cellSpacing=0 cellPadding=0 border=0>
  <TBODY>
  <TR vAlign=top>
    <TD width=15></TD>
    <TD><IMG height=32 src="POSIX Threads Programming.files/question2.gif" 
      width=27></TD>
    <TD>Question: When more than one thread is waiting for a locked mutex, 
      which thread will be granted the lock first after it is released? <BR><INPUT onclick="Answers('pthreads03')" type=button value=Answer></TD></TR></TBODY></TABLE><!---------------------------------------------------------------------------><A 
name=MutexExample><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>Example: Using Mutexes </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 - Using Mutexes</SPAN></B> 
        <UL>This example program illustrates the use of mutex variables in a 
          threads program that performs a dot product. The main data is made 
          available to all threads through a globally accessible structure. Each 
          thread works on a different part of the data. The main thread waits 
          for all the threads to complete their computations, and then it prints 
          the resulting sum. </UL>
        <HR>
        <FONT size=-1><PRE><B>
<FONT color=red>#include &lt;pthread.h&gt;</FONT>
#include &lt;stdio.h&gt;
#include &lt;malloc.h&gt;

/*   
The following structure contains the necessary information  
to allow the function "dotprod" to access its input data and 
place its output into the structure.  This structure is 
unchanged from the sequential version.
*/

typedef struct 
 {
   double      *a;
   double      *b;
   double     sum; 
   int     veclen; 
 } DOTDATA;

/* Define globally accessible variables and a mutex */

#define NUMTHRDS 4
#define VECLEN 100
   DOTDATA dotstr; 
   <FONT color=red>pthread_t callThd[NUMTHRDS];</FONT>
   <FONT color=red>pthread_mutex_t mutexsum;</FONT>

/*
The function dotprod is activated when the thread is created.
All input to this routine is obtained from a structure 
of type DOTDATA and all output from this function is written into
this structure. The benefit of this approach is apparent for the 
multi-threaded program: when a thread is created we pass a single
argument to the activated function - typically this argument
is a thread number. All  the other information required by the 
function is accessed from the globally accessible structure. 
*/

void *dotprod(void *arg)
{

   /* Define and use local variables for convenience */

   int i, start, end, offset, len ;
   double mysum, *x, *y;
   offset = (int)arg;
     
   len = dotstr.veclen;
   start = offset*len;
   end   = start + len;
   x = dotstr.a;
   y = dotstr.b;

   /*
   Perform the dot product and assign result
   to the appropriate variable in the structure. 
   */

   mysum = 0;
   for (i=start; i &lt; end ; i++) 
    {
      mysum += (x[i] * y[i]);
    }

   /*
   Lock a mutex prior to updating the value in the shared
   structure, and unlock it upon updating.
   */
   <FONT color=red>pthread_mutex_lock (&amp;mutexsum);</FONT>
   dotstr.sum += mysum;
   <FONT color=red>pthread_mutex_unlock (&amp;mutexsum);</FONT>

   <FONT color=red>pthread_exit((void*) 0);</FONT>
}

/* 
The main program creates threads which do all the work and then 
print out result upon completion. Before creating the threads,
the input data is created. Since all threads update a shared structure, 
we need a mutex for mutual exclusion. The main thread needs to wait for
all threads to complete, it waits for each one of the threads. We specify
a thread attribute value that allow the main thread to join with the
threads it creates. Note also that we free up handles  when they are
no longer needed.
*/

int main (int argc, char *argv[])
{
   int i;
   double *a, *b;
   int status;
   <FONT color=red>pthread_attr_t attr;</FONT>

   /* Assign storage and initialize values */
   a = (double*) malloc (NUMTHRDS*VECLEN*sizeof(double));
   b = (double*) malloc (NUMTHRDS*VECLEN*sizeof(double));
  
   for (i=0; i &lt; VECLEN*NUMTHRDS; i++)
    {
     a[i]=1;
     b[i]=a[i];
    }

   dotstr.veclen = VECLEN; 
   dotstr.a = a; 
   dotstr.b = b; 
   dotstr.sum=0;

   <FONT color=red>pthread_mutex_init(&amp;mutexsum, NULL);</FONT>
         
   /* Create threads to perform the dotproduct  */
   <FONT color=red>pthread_attr_init(&amp;attr);</FONT>
   <FONT color=red>pthread_attr_setdetachstate(&amp;attr, PTHREAD_CREATE_JOINABLE);</FONT>

	for(i=0;i &lt; NUMTHRDS;i++)
        {
	/* 
	Each thread works on a different set of data.
	The offset is specified by 'i'. The size of
	the data for each thread is indicated by VECLEN.
	*/
	<FONT color=red>pthread_create( &amp;callThd[i], &amp;attr, dotprod, (void *)i);</FONT>
	}

 	<FONT color=red>pthread_attr_destroy(&amp;attr);</FONT>

        /* Wait on the other threads */
	for(i=0;i &lt; NUMTHRDS;i++)
        {
	  <FONT color=red>pthread_join( callThd[i], (void **)&amp;status);</FONT>
	}

   /* After joining, print out the results and cleanup */
   printf ("Sum =  %f \n", dotstr.sum);
   free (a);
   free (b);
   <FONT color=red>pthread_mutex_destroy(&amp;mutexsum);</FONT>
   <FONT color=red>pthread_exit(NULL);</FONT>
}   
</B></PRE><A onclick=blur() 
        href="http://www.llnl.gov/computing/tutorials/workshops/workshop/pthreads/samples/dotprod_serial.c" 
        target=W2><IMG height=20 alt="View source code" 
        src="POSIX Threads Programming.files/source1.gif" width=65 border=0></A> 
        <I>Serial version</I> <BR><A onclick=blur() 
        href="http://www.llnl.gov/computing/tutorials/workshops/workshop/pthreads/samples/dotprod_mutex.c" 
        target=W2><IMG height=20 alt="View source code" 
        src="POSIX Threads Programming.files/source1.gif" width=65 border=0></A> 
        <I>Pthreads version</I> </FONT></TD></TR></TBODY></TABLE></P></UL><!---------------------------------------------------------------------------><A 
name=ConditionVariables><BR><BR></A><A name=ConVarOverview></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>Condition Variables 
  </SPAN></TD></TD></TR></TBODY></TABLE>
<P><SPAN class=heading2>Overview </SPAN>
<P><BR>
<UL>
  <P>
  <LI>Condition variables provide yet another way for threads to synchronize. 
  While mutexes implement synchronization by controlling thread access to data, 
  condition variables allow threads to synchronize based upon the actual value 
  of data. 
  <P></P>
  <LI>Without condition variables, the programmer would need to have threads 
  continually polling (possibly in a critical section), to check if the 
  condition is met. This can be very resource consuming since the thread would 
  be continuously busy in this activity. A condition variable is a way to 
  achieve the same goal without polling. 
  <P></P>
  <LI>A condition variable is always used in conjunction with a mutex lock. 
  <P></P>
  <LI>A representative sequence for using condition variables is shown below. 
  <P>
  <TABLE cellSpacing=0 cellPadding=5 width="90%" border=1>
    <TBODY>
    <TR vAlign=top>
      <TD bgColor=#eeeeee colSpan=2><SPAN class=heading3>Main Thread</SPAN> 
        <UL>
          <LI>Declare and initialize global data/variables which require 
          synchronization (such as "count") 
          <LI>Declare and initialize a condition variable object 
          <LI>Declare and initialize an associated mutex 
          <LI>Create threads A and B to do work </LI></UL></TD></TR>
    <TR vAlign=top>
      <TD width="50%"><SPAN class=heading3>Thread A</SPAN> 
        <UL>
          <LI>Do work up to the point where a certain condition must occur (such 
          as "count" must reach a specified value) 
          <LI>Lock associated mutex and check value of a global variable 
          <LI>Call <TT>pthread_cond_wait()</TT> to perform a blocking wait for 
          signal from Thread-B. Note that a call to <TT>pthread_cond_wait()</TT> 
          automatically and atomically unlocks the associated mutex variable so 
          that it can be used by Thread-B. 
          <LI>When signalled, wake up. Mutex is automatically and atomically 
          locked. 
          <LI>Explicitly unlock mutex 
          <LI>Continue </LI></UL></TD>
      <TD width="50%"><SPAN class=heading3>Thread B</SPAN> 
        <UL>
          <LI>Do work 
          <LI>Lock associated mutex 
          <LI>Change the value of the global variable that Thread-A is waiting 
          upon. 
          <LI>Check value of the global Thread-A wait variable. If it fulfills 
          the desired condition, signal Thread-A. 
          <LI>Unlock mutex. 
          <LI>Continue </LI></UL></TD></TR>
    <TR vAlign=top>
      <TD bgColor=#eeeeee colSpan=2><SPAN class=heading3>Main Thread</SPAN> 
        <UL>Join / Continue </UL></TD></TR></TBODY></TABLE></P></LI></UL><!---------------------------------------------------------------------------><A 
name=ConVarCreation><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>Condition Variables 
  </SPAN></TD></TD></TR></TBODY></TABLE>
<P><SPAN class=heading2>Creating / Destroying Condition Variables </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_cond_init.html" 
        target=W2>pthread_cond_init</A> (condition,attr) 
        <P><A onclick=blur() 
        href="http://www.llnl.gov/computing/tutorials/workshops/workshop/pthreads/man/pthread_cond_destroy.html" 
        target=W2>pthread_cond_destroy</A> (condition) 
        <P><A onclick=blur() 
        href="http://www.llnl.gov/computing/tutorials/workshops/workshop/pthreads/man/pthread_condattr_init.html" 
        target=W2>pthread_condattr_init</A> (attr) 
        <P><A onclick=blur() 
        href="http://www.llnl.gov/computing/tutorials/workshops/workshop/pthreads/man/pthread_condattr_destroy.html" 
        target=W2>pthread_condattr_destroy</A> (attr) 
  </P></B></TT></TD></TR></TBODY></TABLE>
  <P></P>
  <LI>Condition variables must be declared with type <TT>pthread_cond_t</TT>, 
  and must be initialized before they can be used. There are two ways to 
  initialize a condition variable: 
  <OL>
    <P>
    <LI>Statically, when it is declared. For example: <BR><TT>pthread_cond_t 
    myconvar = PTHREAD_COND_INITIALIZER;</TT> 
    <P></P>
    <LI>Dynamically, with the <TT>pthread_cond_init()</TT> routine. The ID of 
    the created condition variable is returned to the calling thread through the 
    <I>condition</I> parameter. This method permits setting condition variable 
    object attributes, <I>attr</I>. </LI></OL>
  <P></P>
  <LI>The opti

⌨️ 快捷键说明

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