// CS 509 - Advanced Programming II
// Spring 2002
//
// Thread iterator example.
#include <algorithm>
#include <iterator>
#include <vector>
#include <iostream>
#include <pthread.h>
#include <errno.h>
#include <cassert>
class thread_iterator
: public std::iterator <
std::input_iterator_tag, // iterator_category
pthread_t, // value_type
std::ptrdiff_t, // difference_type
pthread_t *, // pointer
pthread_t & > { // reference
public:
thread_iterator(unsigned i, void * (* f)(void *))
: cnt(i), tmain(f), tid(0) {
assert(f);
}
thread_iterator()
: cnt(0), tmain(0), tid(0) {
}
thread_iterator(const thread_iterator & ti)
: cnt(ti.cnt), tmain(ti.tmain), tid(ti.tid) {
}
pthread_t operator * () {
if (tid == 0)
ptc(tid, cnt);
return tid;
}
thread_iterator operator ++ () {
ptc(tid, cnt);
return *this;
}
thread_iterator operator ++ (int) {
thread_iterator old(*this);
ptc(tid, cnt);
return old;
}
bool operator == (const thread_iterator & ti) const {
return cnt == ti.cnt;
}
bool operator != (const thread_iterator & ti) const {
return not this->operator == (ti);
}
private:
void ptc(pthread_t & id, unsigned & arg) {
if (arg > 0) {
errno = pthread_create(
&id, NULL, tmain, reinterpret_cast<void *>(arg--));
if (errno) {
perror("pthread_create() failed");
exit(1);
}
}
}
unsigned cnt;
void * (* tmain)(void *);
pthread_t tid;
};
static void
join_waiter(pthread_t tid) {
if (pthread_join(tid, NULL)) {
perror("pthread_join() failed");
exit(1);
}
}
static void *
f(void * arg) {
std::cout << "thread " << reinterpret_cast<unsigned>(arg) << " is alive.\n";
return 0;
}
int main() {
const unsigned max_threads = 10;
std::vector<pthread_t> tids;
std::copy(thread_iterator(max_threads, f),
thread_iterator(),
std::back_inserter(tids));
std::for_each(tids.begin(), tids.end(), join_waiter);
}
// g++ -o ti -ansi -pedantic thread-iterator.cc -lpthread
// $Log: thread-iterator.cc,v $
// Revision 1.2 2004/03/05 18:04:09 rclayton
// Factor common code into ptc().
//
// Revision 1.1 2004/03/05 03:55:54 rclayton
// Initial revision
//
syntax highlighted by Code2HTML, v. 0.9