threads.7
上传用户:shtangtang
上传日期:2007-01-04
资源大小:167k
文件大小:8k
- ." Copyright (c) 1999-2000 Orn E. Hansen <oe.hansen@gamma.telenordia.se>
- ."
- ." Permission is granted to make and distribute verbatim copies of this
- ." manual provided the copyright notice and this permission notice are
- ." preserved on all copies.
- ."
- ." Permission is granted to copy and distribute modified versions of this
- ." manual under the conditions for verbatim copying, provided that the
- ." entire resulting derived work is distributed under the terms of a
- ." permission notice identical to this one
- ."
- .TH THREADS 7 "10 Feb 2000" "Threads 2.0" "Threads C++ Library"
- .SH NAME
- threads - C++ environment, for threaded applications.
- .SH SYNOPSIS
- .B #include <thread.h>
- .sp 2
- .B class threaded : public pthread {
- .sp 0
- .B ...
- .sp 0
- .B int thread(void *);
- .sp 0
- .B ...
- .sp 0
- .B }
- .SH DESCRIPTION
- .I Threads
- is a library of class, that make threaded programming simpler
- and easier to maintain, by providing an abstract class where
- the actual threaded application is a method.
- Several classes are provided with the library, each of which
- has a collection of methods, that provide its basic functions.
- .TP 12
- .B pthread
- This class provides the abstraction for threaded applications. Where
- the thread is an abstract method
- .I int thread(void *)
- which can return a value of type integer, and accept a parameter
- of an unknown type, which is identified by
- .I void *
- and must be broken out by the users specification of the method.
- .TP 12
- .B mutex
- A class for mutual exclusion of parallel processes. It provides
- means to lock and unlock the mutex, so that threads may synchronize
- their access to shared resources.
- .TP 12
- .B cond
- Which provides means of signalling conditions between two
- threads. Several threads can be waiting on a condition variable
- awaiting some occurrance, and the thread providng the signal
- can decide wether it should awake one or all the threads
- waiting on it.
- .TP 12
- .B semaphore
- A historical synchronisation method, which is also provided and
- has a very special use. See
- .I semaphore(3)
- for a discussion on the use it can provide in a C++ threaded
- environment.
- .LP
- Beyond merely providing these methods for a threaded environment
- the
- .I Threads version 2.0 Library
- also provides for process scoping. A program can decide to
- declare its resources as shareable and synchronise itself with
- another program that may or may not be started at the same
- time. The library package, comes with a rich set of example
- programs that demonstrate its use, one of which is a program
- that demonstrates the dining philosopher problem, with the
- use of process scoping.
- .nf
- //
- // This is a philosopher demo, using process scoping.
- #include <thread.h>
- #define MAX_PHILOSOPHERS 5
- int main()
- {
- mutex *p_fork;
- semaphore *sem;
- bool fork_v = false;
- int lfork, rfork, _nr, _forks = MAX_PHILOSOPHERS, _count;
-
- pthread::set_project( "/tmp/philosophy" );
- sem = new semaphore(attributes::process_shared);
- p_fork = new mutex[MAX_PHILOSOPHERS](attributes::process_shared);
- if ( (_nr = sem->post()) > MAX_PHILOSOPHERS ) {
- sem->trywait();
- exit(0);
- }
- _count = _forks;
- _nr -= 1;
- lfork = _nr-1 >= 0 ? _nr-1 : _forks-1;
- rfork = lfork+1 >= _forks ? 0 : lfork+1;
- while(_count-- > 0) {
- cout.form("Philosopher %d: looking for %d,%dn", _nr, lfork, rfork);
- while( fork_v == false ) {
- if (p_fork[lfork].trylock() == 0) {
- if (p_fork[rfork].trylock() == 0)
- fork_v = true;
- else
- p_fork[lfork].unlock();
- }
- }
- cout.form("Philosopher %d: using (%d,%d).n", _nr, lfork, rfork);
- sleep(2);
- fork_v = false;
- cout.form("Philosopher %d: sleepingn", _nr);
- p_fork[lfork].unlock();
- p_fork[rfork].unlock();
- sleep(2);
- }
- cout << _nr << " has finished dining." << endl;
- sem->trywait();
- return 0;
- }
- .fi
- .LP
- This program starts, by creating a project name for its resources. But
- this is a file name, that will be used by the linux kernel to calculate
- a unique key to identify its shared pages with. Since the key is
- calculated from inode numbers, it requires file names to identify
- them by. The command that does this is...
- .nf
- pthread::set_project( "/tmp/philosophy" );
- .fi
- Such a scheme is perfectly acceptable, in most cases, and makes it
- possible for other programs to share its resources without having
- the same program filename.
- After having declared the shared resource name, it starts allocating
- its resources. In the declaration of its resources, it passes
- a special attribute name
- .I attributeees::process_shared
- to their constructor to indicate that the specified resource
- should be shared...
- .nf
- sem = new semaphore(attributes::process_shared);
- p_fork = new mutex[MAX_PHILOSOPHERS](attributes::process_shared);
- .fi
- From this point beyond, these resources are sharable and starting
- several incidents of the same program ( up to 5 in this case )
- will make a full example of the famous dining philosopher problem.
- However, as in the above example it is required for other programs
- that wish to share its resources to identify the resources it
- wants to share. In this case, it may be unwanted for a program
- to actually share the mutexes and only watch how many philosophers
- were actually dining. But, if the program had actually declared
- its mutexes prior to the semaphore, another program would actually
- have to declare the mutexes as well before it actuall got to the
- memory where the semaphore was located.
- .I A program can decide the branch name
- to signify that a given set of resources, can be identified
- with a different identity than other resources.
- So, if the program above would have done
- .nf
- p_fork = new mutex[MAX_PHILOSOPHERS](attributes::process_shared);
- semaphore::project_part( "semaphore" );
- sem = new semaphore(attributes::process_shared);
- .fi
- It would mean, that the semaphore would be identified by a
- filename
- .I /tmp/philosopher_semaphore
- which is easily identifiable, and separate from other
- resources in the program.
- .I The same can be used for cond and mutex classes
- to identify these as seperate branches from the main
- program. Making each resource a separate identity.
- The user can even share his or her own pages of memory, if so
- desired. The
- .I pthread
- class makes it possible for a user, to allocate their own
- shared memory locations. For this purpose, there are two
- methods provided
- .IP
- .I void *pthread::shalloc(size_t)
- .LP
- which allocates shared memory of the specified size, and the
- opposite method
- .IP
- .I pthread::shdealloc(void *)
- .LP
- which returns the memory, allocated by the above method,
- back to a pool of free shared memory.
- Shared memory pages, that aren't used are
- .I always
- returned immediately to the system, and destroyed when they
- aren't used. And the library further installs several signal handlers
- to make sure that signals that normally terminate the users
- application will also destroy the shared memory pages.
- Note: If the user decides to override these signal handlers,
- he is urged to make sure that the
- .B exit()
- system call is used to exit the application. This is
- preferrable since otherwise shared memory will remain in the
- system's swap pages and may cause interference next time an
- application is run.
- .LP
- Suggestions and questions about the threads library should be
- directed to
- .IP
- kdb-list@brevet.nu
- .LP
- Or, to the author specified below. The threads home page is located at:
- .IP
- http://user.tninet.se/~dpn659b/threads.html
- .LP
- .SH AUTHOR
- Version 2.0
- Copyright (C) 1999-2000 Orn E. Hansen <oe.hansen@gamma.telenordia.se>.
- .LP
- Thanks to those who reported their suggestions on how to
- improve the threads library.