| Rogue Wave Standard C++ Library 2.2.1 | Rogue Wave Standard C++ Library 1.2.1 and Tools.h++ 7.0.6 |
|---|---|
|
|
// create a mutex and initialize it pthread_mutex_t the_mutex; #ifdef _PTHREADS_DRAFT4 // for user threads pthread_mutex_init(&the_mutex, pthread_mutexattr_default); #else // for kernel threads pthread_mutex_init(&the_mutex, (pthread_mutexattr_t *)NULL); #endif pthread_mutex_lock(&the_mutex); cout << "something" ... ; pthread_mutex_unlock(&the_mutex);
Note that conditional compilation may be necessary to accommodate both the user threads and the kernel threads interfaces, as in the above example. An alternative might be to compose a buffer with an ostrstream and output with one write. The following example could be used with the cfront compatible libstream.
ostrstream ostr; ostr << "something" /*...*/ ; ostr << " or another" /*...*/ << endl; cout.write(ostr.str(), ostr.pcount()); ostr.rdbuf()->freeze(0);Note that the above example works with with the new library, though with the deprecated ostrstream.
Or something similar can be done with the Rogue Wave Standard C++ Library 2.2.1 (libstd_v2) with standard ostringstream, as in the following example:
ostringstream ostr; ostr << "something" /*...*/ ; ostr << " or another" /*...*/ << endl; cout.write(ostr.str().c_str(), ostr.str().length());Note that cout.flush() may be needed if sharing the file with stdio.
| Rogue Wave Standard C++ Library 2.2.1 | Rogue Wave Standard C++ Library 1.2.1 and Tools.h++ 7.0.6 |
|---|---|
|
|
WARNING: If you do not specify these options as described in the above table, a run-time error will be generated or multi-thread behavior will be incorrect.
void f(ostream &out, int x, int y) {
out << setw(3) << x << setw(10) << y;
}
This function would not be thread safe if called from multiple
threads with the same object, since the "width" in the shared object
could be changed at any time. Therefore, such objects are not
protected from interactions between multiple threads, and the
result of sharing such an object between threads is undefined.
If the same object is shared between threads, a runtime crash, abort, or intermingled output may occur. With the Rogue Wave Standard C++ Library 2.2.1, output may be intermingled but no aborts will occur.
-D_THREAD_SAFE with the
cfront Compatible libstreamcout, cin, cerr, and clog,
you can specify the -D_THREAD_SAFE compile time flag for
any file that includes <iostream.h>.
In this case, a new instance of the object is transparently created for
each thread that uses it. All instances share the same file descriptor.
The f() function in the above example will now work, because it receives
one new "out" object per thread. However, the results of two
simultaneous executions of f() will be mixed in any order in the output.
Using -D_THREAD_SAFE with the global scope operator is not supported for
cout, cin, cerr, and clog.
For example, the following code would generate an error:
::cout << endl;
Note, if you use locks, you need not use the -D_THREAD_SAFE compile time flag since you are now responsible for ensuring thread safety.
libstreamVisible differences would be as follows. In the case of standard iostreams, there is intermingling of each component being inserted. With cfront compatible iostreams, there is intermingling of complete buffers (depending on when endl or flush is called).
-D__HPACC_THREAD_SAFE_RB_TREErb_tree class is involved.
In other words, if the tree header file
(which includes tree.cc) under /opt/aCC/include/ is used,
these libraries are not thread safe.
Most likely, it is indirectly referenced by including the standard C++ library
container class map or set headers,
or by including a RogueWave tools.h++ header like tvset.h,
tpmset.h, tpmset.h, tvset.h, tvmset.h, tvmset.h, tpmap.h, tpmmap.h,
tpmmap.h, tvmap.h, tvmmap.h.
Since changing the rb_tree implementation to
make it thread safe would break binary compatibility,
the preprocessing macro, __HPACC_THREAD_SAFE_RB_TREE, must be defined.
Whether or not this macro is defined
when compiling a file that includes the tree header, its use must
be consistent. For example, a new object file compiled with the macro
defined should not be linked with older ones that were compiled without
the macro defined. Library providers whose library is built with the
the macro defined may need to notify their users to also compile their source
with the macro defined when the tree header is included.
The following example illustrates that you cannot catch an object which has been thrown in a different thread. To do so will result in a runtime abort since HP aC++ finds no available catch handler and terminate is called.
#include <pthread.h>
void foo() {
int i = 10;
throw i;
}
int main() {
pthread_t tid;
try {
ret=pthread_create(&tid, ???, (void*(*)(void*))foo, 0);
}
catch(int n) {}
}