http://groups.google.com/group/comp.programming.threads?hl=en
comp.programming.threads@googlegroups.com
Today's topics:
* a really simple C++ abstraction around pthread_t... - 3 messages, 2 authors
http://groups.google.com/group/comp.programming.threads/browse_thread/thread/44190e3b9ac81a69?hl=en
* looking for elegant C++ abstraction around pthread_key_t... - 2 messages, 1
author
http://groups.google.com/group/comp.programming.threads/browse_thread/thread/92098dc36b54f96a?hl=en
* Can semaphore operations replace mutex+cond var? - 1 messages, 1 author
http://groups.google.com/group/comp.programming.threads/browse_thread/thread/38a7afe0e9891fd1?hl=en
* What benefits do thread-local variables (threadvar) have ? - 4 messages, 2
authors
http://groups.google.com/group/comp.programming.threads/browse_thread/thread/eafc429b15d5b683?hl=en
* some issue w.r.t. pthread_cond_signal( ) - 1 messages, 1 author
http://groups.google.com/group/comp.programming.threads/browse_thread/thread/a0280bc019886ffc?hl=en
==============================================================================
TOPIC: a really simple C++ abstraction around pthread_t...
http://groups.google.com/group/comp.programming.threads/browse_thread/thread/44190e3b9ac81a69?hl=en
==============================================================================
== 1 of 3 ==
Date: Thurs, Oct 30 2008 2:44 pm
From: Szabolcs Ferenczi
On Oct 30, 10:39 pm, "Chris M. Thomasson" <n...@spam.invalid> wrote:
> I use the following technique in all of my C++ projects; here is the example
> code with error checking omitted for brevity:
> _________________________________________________________________
> /* Simple Thread Object
> ______________________________________________________________*/
> #include <pthread.h>
>
> extern "C" void* thread_entry(void*);
>
> class thread_base {
> pthread_t m_tid;
> friend void* thread_entry(void*);
> virtual void on_active() = 0;
>
> public:
> virtual ~thread_base() = 0;
>
> void active_run() {
> pthread_create(&m_tid, NULL, thread_entry, this);
> }
>
> void active_join() {
> pthread_join(m_tid, NULL);
> }
>
> };
>
> thread_base::~thread_base() {}
>
> void* thread_entry(void* state) {
> reinterpret_cast<thread_base*>(state)->on_active();
> return 0;
>
> }
>
> template<typename T>
> struct active : public T {
> active() : T() {
> this->active_run();
> }
>
> ~active() {
> this->active_join();
> }
>
> template<typename T_p1>
> active(T_p1 p1) : T(p1) {
> this->active_run();
> }
>
> template<typename T_p1, typename T_p2>
> active(T_p1 p1, T_p2 p2) : T(p1, p2) {
> this->active_run();
> }
>
> // [and on and on for more params...]
>
> };
>
> /* Simple Usage Example
> ______________________________________________________________*/
> #include <string>
> #include <cstdio>
>
> class worker : public thread_base {
> std::string const m_name;
>
> void on_active() {
> std::printf("(%p)->worker(%s)::on_thread_entry()\n",
> (void*)this, m_name.c_str());
> }
>
> public:
> worker(std::string const& name)
> : m_name(name) {
> std::printf("(%p)->worker(%s)::my_thread()\n",
> (void*)this, m_name.c_str());
> }
>
> ~worker() {
> std::printf("(%p)->worker(%s)::~my_thread()\n",
> (void*)this, m_name.c_str());
> }
>
> };
>
> class another_worker : public thread_base {
> unsigned const m_id;
> std::string const m_name;
>
> void on_active() {
> std::printf("(%p)->my_thread(%u/%s)::on_thread_entry()\n",
> (void*)this, m_id, m_name.c_str());
> }
>
> public:
> another_worker(unsigned const id, std::string const& name)
> : m_id(id), m_name(name) {
> }
>
> };
>
> int main(void) {
> {
> active<worker> workers[] = {
> "Chris",
> "John",
> "Jane",
> "Steve",
> "Richard",
> "Lisa"
> };
>
> active<another_worker> other_workers[] = {
> active<another_worker>(21, "Larry"),
> active<another_worker>(87, "Paul"),
> active<another_worker>(43, "Peter"),
> active<another_worker>(12, "Shelly"),
> };
> }
>
> std::puts("\n\n\n__________________\nhit <ENTER> to exit...");
> std::fflush(stdout);
> std::getchar();
> return 0;}
>
> _________________________________________________________________
>
> I personally like this technique better than Boost. I find it more straight
> forward and perhaps more object oriented, the RAII nature of the `active'
> helper class does not hurt either. Also, I really do think its more
> "efficient" than Boost in the way it creates threads because it does not
> copy anything...
>
> IMHO, the really nice thing about it would have to be the `active' helper
> class. It allows me to run and join any object from the ctor/dtor that
> exposes a common interface of (T::active_run/join). Also, it allows me to
> pass a variable number of arguments to the object it wraps directly through
> its ctor; this is fairly convenient indeed...
>
> Any suggestions on how I can improve this construct?
Now it is better that you have taken the advice about the terminology
(active):
http://groups.google.com/group/comp.lang.c++/msg/6e915b5211cce641
Best Regards,
Szabolcs
== 2 of 3 ==
Date: Thurs, Oct 30 2008 2:53 pm
From: "Chris M. Thomasson"
"Szabolcs Ferenczi" <szabolcs.ferenczi@gmail.com> wrote in message
news:de3350c2-558d-4059-8148-7a1c49f810c4@u29g2000pro.googlegroups.com...
On Oct 30, 10:39 pm, "Chris M. Thomasson" <n...@spam.invalid> wrote:
> > I use the following technique in all of my C++ projects; here is the
> > example
> > code with error checking omitted for brevity:
> > _________________________________________________________________
> [...]
> > _________________________________________________________________
> >
> > I personally like this technique better than Boost. I find it more
> > straight
> > forward and perhaps more object oriented, the RAII nature of the
> > `active'
> > helper class does not hurt either. Also, I really do think its more
> > "efficient" than Boost in the way it creates threads because it does not
> > copy anything...
> >
> > IMHO, the really nice thing about it would have to be the `active'
> > helper
> > class. It allows me to run and join any object from the ctor/dtor that
> > exposes a common interface of (T::active_run/join). Also, it allows me
> > to
> > pass a variable number of arguments to the object it wraps directly
> > through
> > its ctor; this is fairly convenient indeed...
> >
> > Any suggestions on how I can improve this construct?
> Now it is better that you have taken the advice about the terminology
> (active):
> http://groups.google.com/group/comp.lang.c++/msg/6e915b5211cce641
Yeah; I think your right.
== 3 of 3 ==
Date: Thurs, Oct 30 2008 3:16 pm
From: "Chris M. Thomasson"
"Chris M. Thomasson" <no@spam.invalid> wrote in message
news:dIpOk.15$kd5.3@newsfe01.iad...
>I use the following technique in all of my C++ projects; here is the
>example code with error checking omitted for brevity:
> _________________________________________________________________
[...]
> _________________________________________________________________
>
[...]
> Any suggestions on how I can improve this construct?
One addition I forgot to add would be creating an explict `guard' helper
object within the `active' helper object so that one can create objects and
intervene between its ctor and when it actually gets ran... Here is full
example code showing this moment:
_________________________________________________________________
/* Simple Thread Object
______________________________________________________________*/
#include <pthread.h>
extern "C" void* thread_entry(void*);
class thread_base {
pthread_t m_tid;
friend void* thread_entry(void*);
virtual void on_active() = 0;
public:
virtual ~thread_base() = 0;
void active_run() {
pthread_create(&m_tid, NULL, thread_entry, this);
}
void active_join() {
pthread_join(m_tid, NULL);
}
};
thread_base::~thread_base() {}
void* thread_entry(void* state) {
reinterpret_cast<thread_base*>(state)->on_active();
return 0;
}
template<typename T>
struct active : public T {
struct guard {
T& m_object;
guard(T& object) : m_object(object) {
m_object.active_run();
}
~guard() {
m_object.active_join();
}
};
active() : T() {
this->active_run();
}
~active() {
this->active_join();
}
template<typename T_p1>
active(T_p1 p1) : T(p1) {
this->active_run();
}
template<typename T_p1, typename T_p2>
active(T_p1 p1, T_p2 p2) : T(p1, p2) {
this->active_run();
}
// [and on and on for more params...]
};
/* Simple Usage Example
______________________________________________________________*/
#include <string>
#include <cstdio>
class worker : public thread_base {
std::string const m_name;
void on_active() {
std::printf("(%p)->worker(%s)::on_active()\n",
(void*)this, m_name.c_str());
}
public:
worker(std::string const& name)
: m_name(name) {
std::printf("(%p)->worker(%s)::my_thread()\n",
(void*)this, m_name.c_str());
}
~worker() {
std::printf("(%p)->worker(%s)::~my_thread()\n",
(void*)this, m_name.c_str());
}
};
class another_worker : public thread_base {
unsigned const m_id;
std::string const m_name;
void on_active() {
std::printf("(%p)->another_worker(%u/%s)::on_active()\n",
(void*)this, m_id, m_name.c_str());
}
public:
another_worker(unsigned const id, std::string const& name)
: m_id(id), m_name(name) {
}
};
int main(void) {
{
worker w1("Amy");
worker w2("Kim");
worker w3("Chris");
another_worker aw1(123, "Kelly");
another_worker aw2(12345, "Tim");
another_worker aw3(87676, "John");
active<thread_base>::guard w12_aw12[] = {
w1, w2, w3,
aw1, aw2, aw3
};
active<worker> workers[] = {
"Jim",
"Dave",
"Regis"
};
active<another_worker> other_workers[] = {
active<another_worker>(999, "Jane"),
active<another_worker>(888, "Ben"),
active<another_worker>(777, "Larry")
};
}
std::puts("\n\n\n__________________\nhit <ENTER> to exit...");
std::fflush(stdout);
std::getchar();
return 0;
}
_________________________________________________________________
Take notice of the following code snippet residing within main:
worker w1("Amy");
worker w2("Kim");
worker w3("Chris");
another_worker aw1(123, "Kelly");
another_worker aw2(12345, "Tim");
another_worker aw3(87676, "John");
active<thread_base>::guard w12_aw12[] = {
w1, w2, w3,
aw1, aw2, aw3
};
This shows how one can make use of the guard object. The objects are fully
constructed, and they allow you do go ahead and do whatever you need to do
with them _before_ you actually run/join them. This can be a very convenient
ability.
==============================================================================
TOPIC: looking for elegant C++ abstraction around pthread_key_t...
http://groups.google.com/group/comp.programming.threads/browse_thread/thread/92098dc36b54f96a?hl=en
==============================================================================
== 1 of 2 ==
Date: Thurs, Oct 30 2008 4:48 pm
From: "Chris M. Thomasson"
Here is what I am playing around with now:
_________________________________________________________________
/* Simple TSD Object
______________________________________________________________*/
#include <pthread.h>
#include <cstdio>
#if defined(_MSC_VER)
# define DECLSPEC_CDECL __cdecl
#elif defined(__GNUC__)
# define DECLSPEC_CDECL __attribute__((cdecl))
#else
# error MSVC or GCC REQUIRED!!!!! ;^(...
No comments:
Post a Comment