The C++ interface to the Dinkum Threads Library is very similar to the
thread support interface defined in the
boost.threads
library for C++.
Some details of this implementation differ from
the boost.threads implementation. For example, in this implementation classes and
functions are enclosed in namespace Dinkum/threads instead of
namespace boost. Implementation differences are marked as such,
throughout this document, by a link to this paragraph.
The C++ interface consists of several headers:
"Dinkum/threads/condition"
-- for defining a class that implements condition variables"Dinkum/threads/exceptions"
-- for defining several classes useful for reporting exceptions"Dinkum/threads/mutex"
-- for defining classes that implement mutual exclusion"Dinkum/threads/once"
-- for ensuring that initialization code is executed only once, from the first
thread that needs the initialization"Dinkum/threads/recursive_mutex"
-- for defining classes that implement mutual exclusion"Dinkum/threads/tss"
-- for defining a template class that supports thread-specific data"Dinkum/threads/xtime"
-- for defining a struct and functions for high-resolution time operationsHere is a sample program to illustrate the use of the C++ interface:
#include <iostream>
#include <stdlib.h>
#include "Dinkum/threads/condition"
#include "Dinkum/threads/mutex"
#include "Dinkum/threads/once"
#include "Dinkum/threads/thread"
#include "Dinkum/threads/tss"
#include "Dinkum/threads/xtime"
static const int data_size = 20;
static int data[data_size];
static int begin;
static int end;
static const int data_limit = 100;
class flag
{ // predicate class
public:
void set() {flg = true; }
void clear() {flg = false; }
bool operator ()() {return flg; }
private:
static bool flg;
};
bool flag::flg;
static flag array_not_full;
static Dinkum::threads::once_flag init_full_flag = Dinkum::threads::once_init;
static void init_full()
{ // initialize array_not_full object from first calling thread
array_not_full.set();
}
// synchronization objects
static Dinkum::threads::mutex data_mtx;
static Dinkum::threads::condition array_full_c;
static Dinkum::threads::condition array_empty_c;
// thread-specfic storage
static Dinkum::threads::thread_specific_ptr<int> val;
static void setup()
{ // initialize thread data
Dinkum::threads::call_once(init_full, init_full_flag);
val.reset(new int);
*val = 0;
}
static void delay()
{ // delay randomly from 0 to 200 milliseconds
xtime xt;
xtime_get(&xt, TIME_UTC);
xt.nsec += (rand() * 200) / (RAND_MAX + 1) * 1000000;
Dinkum::threads::thread::sleep(xt);
}
static void producer()
{ // insert sequential values from 0 to data_limit into queue
setup();
while (*val < data_limit)
{ // insert *val into queue
delay();
Dinkum::threads::mutex::scoped_lock lock(data_mtx);
array_full_c.wait(lock, array_not_full);
data[end++] = (*val)++;
if (end == data_size)
end = 0;
if (end + 1 == begin
|| end + 1 == data_size && begin == 0)
array_not_full.clear();
array_empty_c.notify_one();
}
}
static bool finished = false;
static void consumer()
{ // remove data values from queue and display values
setup();
while (!finished || begin != end)
{ // remove and display data values
delay();
Dinkum::threads::mutex::scoped_lock lock(data_mtx);
while (!finished && begin == end)
array_empty_c.wait(lock);
if (begin != end)
{ // remove and display a data value
*val = -data[begin++];
std::cout << *val << '\n';
if (begin == data_size)
begin = 0;
array_not_full.set();
array_full_c.notify_one();
}
}
}
int main()
{ // create a consumer thread and two producer threads
Dinkum::threads::thread thr0(consumer);
Dinkum::threads::thread_group group;
group.create_thread(producer);
group.create_thread(producer);
group.join_all();
{ // lock mutex while setting finished
Dinkum::threads::mutex::scoped_lock lock(data_mtx);
finished = true;
}
thr0.join();
return 0;
}
The C++ interface makes suitable use of templates and classes, but its functionality is otherwise quite similar to that described for the C interface.
See also the Table of Contents and the Index.
Copyright © 1992-2013 by Dinkumware, Ltd. Portions derived from work copyright © 2001 by William E. Kempf. All rights reserved.