threads.7
上传用户:shtangtang
上传日期:2007-01-04
资源大小:167k
文件大小:8k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. ." Copyright (c) 1999-2000 Orn E. Hansen <oe.hansen@gamma.telenordia.se>
  2. ."
  3. ." Permission is granted to make and distribute verbatim copies of this
  4. ." manual provided the copyright notice and this permission notice are
  5. ." preserved on all copies.
  6. ."
  7. ." Permission is granted to copy and distribute modified versions of this
  8. ." manual under the conditions for verbatim copying, provided that the
  9. ." entire resulting derived work is distributed under the terms of a
  10. ." permission notice identical to this one
  11. ."                                                                            
  12. .TH THREADS 7 "10 Feb 2000" "Threads 2.0" "Threads C++ Library"
  13. .SH NAME
  14. threads - C++ environment, for threaded applications.
  15. .SH SYNOPSIS
  16. .B        #include <thread.h>
  17. .sp 2
  18. .B        class threaded : public pthread {
  19. .sp 0
  20. .B        ...
  21. .sp 0
  22. .B        int thread(void *);
  23. .sp 0
  24. .B        ...
  25. .sp 0
  26. .B        }
  27. .SH DESCRIPTION
  28. .I Threads
  29. is a library of class, that make threaded programming simpler
  30. and easier to maintain, by providing an abstract class where
  31. the actual threaded application is a method.
  32. Several classes are provided with the library, each of which
  33. has a collection of methods, that provide its basic functions.
  34. .TP 12
  35. .B pthread
  36. This class provides the abstraction for threaded applications.  Where
  37. the thread is an abstract method
  38. .I int thread(void *)
  39. which can return a value of type integer, and accept a parameter
  40. of an unknown type, which is identified by
  41. .I void *
  42. and must be broken out by the users specification of the method.
  43. .TP 12
  44. .B mutex
  45. A class for mutual exclusion of parallel processes.  It provides
  46. means to lock and unlock the mutex, so that threads may synchronize
  47. their access to shared resources.
  48. .TP 12
  49. .B cond
  50. Which provides means of signalling conditions between two
  51. threads.  Several threads can be waiting on a condition variable
  52. awaiting some occurrance, and the thread providng the signal
  53. can decide wether it should awake one or all the threads
  54. waiting on it.
  55. .TP 12
  56. .B semaphore
  57. A historical synchronisation method, which is also provided and
  58. has a very special use.  See
  59. .I semaphore(3)
  60. for a discussion on the use it can provide in a C++ threaded
  61. environment.
  62. .LP
  63. Beyond merely providing these methods for a threaded environment
  64. the
  65. .I Threads version 2.0 Library
  66. also provides for process scoping.  A program can decide to
  67. declare its resources as shareable and synchronise itself with
  68. another program that may or may not be started at the same
  69. time.  The library package, comes with a rich set of example
  70. programs that demonstrate its use, one of which is a program
  71. that demonstrates the dining philosopher problem, with the
  72. use of process scoping.
  73. .nf
  74. //
  75. // This is a philosopher demo, using process scoping.
  76. #include <thread.h>
  77. #define MAX_PHILOSOPHERS          5
  78. int main()
  79. {
  80.   mutex *p_fork;
  81.   semaphore *sem;
  82.   bool fork_v = false;
  83.   int lfork, rfork, _nr, _forks = MAX_PHILOSOPHERS, _count;
  84.   
  85.   pthread::set_project( "/tmp/philosophy" );
  86.   sem    = new semaphore(attributes::process_shared);
  87.   p_fork = new mutex[MAX_PHILOSOPHERS](attributes::process_shared);
  88.   if ( (_nr = sem->post()) > MAX_PHILOSOPHERS ) {
  89.     sem->trywait();
  90.     exit(0);
  91.   }
  92.   _count = _forks;
  93.   _nr -= 1;
  94.   lfork = _nr-1 >= 0 ? _nr-1 : _forks-1;
  95.   rfork = lfork+1 >= _forks ? 0 : lfork+1;
  96.   while(_count-- > 0) {
  97.     cout.form("Philosopher %d: looking for %d,%dn", _nr, lfork, rfork);
  98.     while( fork_v == false ) {
  99.       if (p_fork[lfork].trylock() == 0) {
  100. if (p_fork[rfork].trylock() == 0)
  101.   fork_v = true;
  102. else
  103.   p_fork[lfork].unlock();
  104.       }
  105.     }
  106.     cout.form("Philosopher %d: using (%d,%d).n", _nr, lfork, rfork);
  107.     sleep(2);
  108.     fork_v = false;
  109.     cout.form("Philosopher %d: sleepingn", _nr);
  110.     p_fork[lfork].unlock();
  111.     p_fork[rfork].unlock();
  112.     sleep(2);
  113.   }
  114.   cout << _nr << " has finished dining." << endl;
  115.   sem->trywait();
  116.   return 0;
  117. }
  118. .fi
  119. .LP
  120. This program starts, by creating a project name for its resources.  But
  121. this is a file name, that will be used by the linux kernel to calculate
  122. a unique key to identify its shared pages with.  Since the key is
  123. calculated from inode numbers, it requires file names to identify 
  124. them by.  The command that does this is...
  125. .nf
  126.   pthread::set_project( "/tmp/philosophy" );
  127. .fi
  128. Such a scheme is perfectly acceptable, in most cases, and makes it
  129. possible for other programs to share its resources without having
  130. the same program filename.
  131. After having declared the shared resource name, it starts allocating
  132. its resources.  In the declaration of its resources, it passes
  133. a special attribute name
  134. .I attributeees::process_shared
  135. to their constructor to indicate that the specified resource
  136. should be shared...
  137. .nf
  138.   sem    = new semaphore(attributes::process_shared);
  139.   p_fork = new mutex[MAX_PHILOSOPHERS](attributes::process_shared);
  140. .fi
  141. From this point beyond, these resources are sharable and starting
  142. several incidents of the same program ( up to 5 in this case )
  143. will make a full example of the famous dining philosopher problem.
  144. However, as in the above example it is required for other programs
  145. that wish to share its resources to identify the resources it
  146. wants to share.  In this case, it may be unwanted for a program
  147. to actually share the mutexes and only watch how many philosophers
  148. were actually dining.  But, if the program had actually declared
  149. its mutexes prior to the semaphore, another program would actually
  150. have to declare the mutexes as well before it actuall got to the
  151. memory where the semaphore was located.
  152. .I A program can decide the branch name
  153. to signify that a given set of resources, can be identified
  154. with a different identity than other resources.
  155. So, if the program above would have done
  156. .nf
  157.   p_fork = new mutex[MAX_PHILOSOPHERS](attributes::process_shared);
  158.   semaphore::project_part( "semaphore" );
  159.   sem    = new semaphore(attributes::process_shared);
  160. .fi
  161. It would mean, that the semaphore would be identified by a
  162. filename
  163. .I /tmp/philosopher_semaphore
  164. which is easily identifiable, and separate from other
  165. resources in the program.
  166. .I The same can be used for cond and mutex classes
  167. to identify these as seperate branches from the main
  168. program.  Making each resource a separate identity.
  169. The user can even share his or her own pages of memory, if so
  170. desired.  The
  171. .I pthread
  172. class makes it possible for a user, to allocate their own
  173. shared memory locations.  For this purpose, there are two
  174. methods provided
  175. .IP
  176. .I void *pthread::shalloc(size_t)
  177. .LP
  178. which allocates shared memory of the specified size, and the
  179. opposite method
  180. .IP
  181. .I pthread::shdealloc(void *)
  182. .LP
  183. which returns the memory, allocated by the above method,
  184. back to a pool of free shared memory.
  185. Shared memory pages, that aren't used are
  186. .I always
  187. returned immediately to the system, and destroyed when they
  188. aren't used.  And the library further installs several signal handlers
  189. to make sure that signals that normally terminate the users
  190. application will also destroy the shared memory pages.
  191. Note: If the user decides to override these signal handlers,
  192. he is urged to make sure that the
  193. .B exit()
  194. system call is used to exit the application.  This is
  195. preferrable since otherwise shared memory will remain in the
  196. system's swap pages and may cause interference next time an
  197. application is run.
  198. .LP
  199. Suggestions and questions about the threads library should be
  200. directed to
  201. .IP
  202. kdb-list@brevet.nu
  203. .LP
  204. Or, to the author specified below. The threads home page is located at:
  205. .IP
  206. http://user.tninet.se/~dpn659b/threads.html
  207. .LP
  208. .SH AUTHOR
  209. Version 2.0
  210. Copyright (C) 1999-2000 Orn E. Hansen <oe.hansen@gamma.telenordia.se>.
  211. .LP
  212. Thanks to those who reported their suggestions on how to
  213. improve the threads library.