🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.programming.threads
Article #3

Re: Looking for best design for using pthreads in C++ objects

#3
From: Nasser Abbasi
Date: Tue, 20 Feb 1996 08:00
85 lines
5029 bytes
In article <3128ff8b.666031216@news.clark.net>, anderson@clark.net (Thom Anderson) says:
>
>I am starting to port a design that was meant to be implemented in Ada to a
>C++/UNIX platform.  I don't want to get involved in any language religion here,
>but it will be much harder to handle tasking with C++.  My best alternative
>(maybe only - since I must be POSIX compliant) is to use pthreads.
>
>I have used pthreads from C before but not from C++.  I have a couple of ideas
>in mind but neither is elegant.  Does anyone have any experience with
>C++/Pthreads and no of some good design solutions, tips, or ideas???
>

I have implemented a C++ Base Thread class that allows threads cross 
communications using message queues. 

The idea is that you have a base thread class, with public interface
access functions to create a thread (can be implemented using Pthread
or whatever thread package you have), and to READ/WRITE from thread
Input and Output Queues. You also need to have a pure virtual 
function that is the address of thread function code itself which the
derived classes have to provide. This way each specialized class can use
different thread functions. 

Now, assume you have created 2 threads objects, A and B. A uses function
A_foo() as the thread function, and B say uses B_foo() as the B thread
function.

For A to send a message to B, A will invoke a public access function in B
that will deposit a message inside a private Queue in B and will then wake
up B (B thread id is saved in private part of B class object )and return. 

Each thread can once in a while can check its input Queue to see if it has 
messages to process. If no message, it will sleep until awakened (or 
sleep for certain period, then tries again etc...).

If you want to implement a driver type of thread, (passive thread) you can
also have the thread object contain an output Queue (in addition to 
Input Queue), and the thread will deposit processed messages (work 
completed) in its output Queue and will then wake any waiting thread on
its output Queue (the readers). (in first-in-first_out fashion).

Each reader will invoke a READ access public function in the thread class,
where this READ access function will access the thread private output
Queue and if there is data, it will remove it, and return, else it will
sleep (block) on the Queue (saves its thread_id in waiters Queue) so
that when the driver thread has data to send out, it will put it in its
output Queue, check the waiters/readers queue, wake up the first in 
line using the reader thread_id). Offcourse you do not have to have
the read block if there is no data. you can have a time_out value, or
other combination.

I do not know Pthreads much, so I do not know if you also need some 
kind of signal number to use in addition to the thread_id to wake up
a thread (You need to look at the Pthread Wake thread API), but if you
do, that is easy to also pass along with the thread_id to allow the 
other thread to wake your thread. (i.e. each Input and Output Queue 
for each thread  will have a signal number associated with it).

All in All, you need to spend good time designing the thread class,
and hide all the threads-cross communications in the private part of
the class. Using Queues to accomplish the message exchanging is the 
most natural way.

One thing to worry about is how much time a caller thread will spend
in the access function of the other thread object. While executing 
the access function inside one thread object the client thread is 
executing in its own  context ,which might have higher priority that
the called thread object, and so things like blocking inside the 
access function need to be thought out well to make sure that is 
what you want to do. (to prevent among other things possible dead-lock).

It is really not that hard, I have implemented the complete class in about
1-2 week, it is 3 layers in class hierarchy, and it is about 500-600 
lines of code (and this was the first time I looked at this problem
of using C++ classes and threads.

offcourse you need to have access to thread-safe Queue classes.

If you on the other hand decide to use Ada , you'll have easier time,
since Ada as you know already solves many of these problems for you, 
by providing tasks and protected objects, the Requeue facility, Rendezvous,
Asynchronous transfer of control, and many other features for
task-to-task interactions.

Nasser
Technical Details
Message-ID: <4gbv3j$g08@qualcomm.com>
Path: arc1-ca.pugleaf.net!qualcomm.com!usenet
References: <3128ff8b.666031216@news.clark.net>

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!qualcomm.com!usenet
From: nabbasi@qualcomm.com (Nasser Abbasi)
Newsgroups: comp.programming.threads,comp.lang.c++,comp.unix.osf.osf1,comp.unix.programmer,comp.object
Subject: Re: Looking for best design for using pthreads in C++ objects
Date: 20 Feb 1996 08:00:51 GMT
Organization: QUalcomm Inc.
Message-ID: <4gbv3j$g08@qualcomm.com>
References: <3128ff8b.666031216@news.clark.net>
Reply-To: x!news.be.innet.net!INbe.net!usenet
NNTP-Posting-Host: annex-p15.qualcomm.com
X-Newsreader: WinVN 0.90.4