Wefts++ does not pretends to be a bleeding edge research library; what Wefts++ wants to be is just a set of utility objects making multi-threading with C++ easier, that will lay gracefully on your C++ application design.
Wefts++ aims to help you develop C++ multi-threading application easily and swiftly. Thread programming is an art, and wefts is your paintbrush
It is also possible to get latest development status of Wefts by downloading the CVS archive:
cvs -z9 -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/wefts login Password: <press enter here> cvs -z9 -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/wefts co wefts
./configure make make install (** read note)
should be enough. Wefts are installed by default into /usr/local/lib/wefts. That directory will contain an include/ subdirectory, where all the include files are added and lib/ subdirectory, where you can found static (and if you care to build them, dynamic) libraries.
You can change this default with the option:
./configure --prefix=/my/favorite/
You could i.e. install wefts libs under /usr/libs and include files under /usr/include by just configuring with --prefix=/usr (if you find this library really useful :-). You could also set specific destination for wefts headers and libraries. In example:
./configure --prefix=/usr --libdir=lib/wefts --includedir=include/wefts
will move libraries and includes in your system standard directory, but under wefts subdirectory (/usr/include/wefts for headers and /usr/lib/wefts for libraries).
aclocal libtoolize --automake autoconf autoheader automake -a
And then you can continue with configure, make and make install. "automake -a" is important, as it will create the standard GNU support utilities to do a clean configure/make process.
Dynamic libraries can be built by passing --enabled-shared to configure. Anyhow, wefts is a very small library, and most of it is held in inline C++ methods; for this reason, using only the static library version makes perfectly sense.
To install the package, you need libpthread.a to be in /usr/lib.
The command rpm -ivh wefts-...rpm will be enough.
If you have installed using rpm, the command rpm -e wefts will remove the package.
However, we present here a minimal survival guide on how to compile and use wefts.
To test if your installation is correct, check out this test:
// $Id: weftstest.cpp,v 1.1 2003/08/16 20:45:57 jonnymind Exp $ // weftstest.cpp - an introductory test // // This program is free software - GPL 2.0 license // (C) Giancarlo Niccolai // // NOTE: this program is demonstrative and hence not compiled // in the make process of Wefts test suite. // #include <wefts.h> #include <iostream> using namespace Wefts; using namespace std; class MyThread: public Thread { void *run() { cout << "Begin of thread" << sequence() -1 << endl; Sleep( 2.5 ); cout << "End of thread" << sequence() -1 << endl; return 0; } }; int main( int argc, char *argv[] ) { for ( int i = 0;i < 4; i ++ ) { MyThread *th = new MyThread(); th->start(); } //we'll wait for our children to terminate: runningThreads.until( 1 ); // until there is only 1 thread left (myself). cout << "Main thread done!" << endl; return 0; }
00001 // $Id: weftstest.cpp,v 1.1 2003/08/16 20:45:57 jonnymind Exp $ 00002 // weftstest.cpp - an introductory test 00003 // 00004 // This program is free software - GPL 2.0 license 00005 // (C) Giancarlo Niccolai 00006 // 00007 // NOTE: this program is demonstrative and hence not compiled 00008 // in the make process of Wefts test suite. 00009 // 00010 00011 #include <wefts.h> 00012 #include <iostream> 00013 00014 using namespace Wefts; 00015 using namespace std; 00016 00017 class MyThread: public Thread 00018 { 00019 void *run() 00020 { 00021 cout << "Begin of thread" << sequence() -1 << endl; 00022 Sleep( 2.5 ); 00023 cout << "End of thread" << sequence() -1 << endl; 00024 return 0; 00025 } 00026 }; 00027 00028 int main( int argc, char *argv[] ) 00029 { 00030 for ( int i = 0;i < 4; i ++ ) { 00031 MyThread *th = new MyThread(); 00032 th->start(); 00033 } 00034 00035 //we'll wait for our children to terminate: 00036 runningThreads.until( 1 ); // until there is only 1 thread left (myself). 00037 00038 cout << "Main thread done!" << endl; 00039 return 0; 00040 } 00041
This simple program can be compiled using the command
$ gcc -o weftstest $(wefts-conf -c) weftstest.cpp $(wefts-conf -s -l)
This command will call wefts-conf two times; the first one will provide some basic C++ flag, including the "include" dir that is needed to do #include <wefts.h>. The second one will tell where to get the wefts library that has to be linked.
If you don't have installed dynamic libraries, (that is, if you don't have enabled them with --enable-shared in configure script), that "-s" option in wefts-conf isn't necessary. In fact, that option just tells to get exactly the static library. Wefts is a very small library (under 50 Kb), so it is possible that the final developer does not want to link against dynamic libraries, with the need to install them everywhere the program has to run.
We have removed the code -s switch in the first line, so, now, we must tell where the dynamic libs are. Wefts-conf has also that ability. The LD_LIBRARY_PATH can also be set at user login, or globally for the whole top level environment, but it is advisable not doing so.gian@head$ gcc -o weftstest $(wefts-conf -c) weftstest.cpp $(wefts-conf -l) gian@head$ ./weftstest ./weftstest: error while loading shared libraries: libwefts.so.1: cannot open shared object file: No such file or directory gian@head$ LD_LIBRARY_PATH=$(wefts-conf -p) ./weftstest Begin of thread1 ... ... Main thread done! gian@head$
So, what can you do now? The main class here is Wefts::Thread; have a look at it. Then you will need some way to synchronize threads: Wefts::Mutex and Wefts::RMutex are what you are searching for.
If you are accustomed with posix condition and signals, the Wefts::Condition, Wefts::FastCondition and Wefts::RCondition classes are implementing that model. If you are not accustomed with them, or if you have enough of condition signaling, well, have a look at them anyway; you could find new way to use them in this C++ object oriented environment. They are absolutely excellent to send safely a data that is produced in a thread to another thread that is waiting for that. (If you use them directly, and if you plan to use thread cancellation, be sure to read Condition cleanup)
A little step further is required for Wefts::XMutex, Wefts::RWMutex and Wefts::RRWMutex.
Then, when you have a certain mastery with this classes, have a look at the Wefts::Barrier, Wefts::RingBuffer, the Wefts::Subscription and finally the Wefts::MoaningThread (TM). -- this (TM) is a joke.
They are somehow self explanatory, and are worth a look anyway.
Each one is meant to do some MESSY test with the library thing. You are supposed to read the header that is displayed at program begin; if it goes away too fast, it is because you are supposed to read it by scrolling back and then see the results of the experiments with caml, after the program is finished; you may also want to to dump the results by redirecting them to a file. In the test sources there are LOTS of comments explaining why certain things are done in certain ways; if you want to learn Wefting, that is a fairly good point to start.
But ... to be honest in release 0.9 there is a fairly good section explaining how to use basic conditions and mutexes; big issues (like the most powerful objects) are left out, but you may want to check Some example.
Enjoy Wefting!
Giancarlo Niccolai