473,387 Members | 1,569 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,387 software developers and data experts.

Polymorphism, pthreads, multi-threading, and libstdc++

Problem Background:
I am working on a thin wrapper for the pthreads interface on linux, and have
encountered frustrating behavior. The idea is to have a "PosixThread" class
that any class can inherit from. A child then only needs to define a
virtual "executive" method that has the thread code for the child object,
and the threading setup and management are automatic then. The thread
creation takes place in the PosixThread base class with a pthread_create
call that gets the address of a static member function that calls the
'executive' function, i.e. the polymorphic executive. The parameter passed
to the static member function is the 'this' pointer which points to the
object being created.

Problem Statement:
The problem I am experiencing is that in a fairly new distro of linux
(mandrake 9.1) calling pthread_create from the base class's constructor
(with this as a parameter) results in a 'pure virtual method called'
run-time error. However, in an older linux distro (redhat 7.3) everything
works as expected.

I suspect that using the 'this' pointer in the Base class's constructor is
probably not something that should be done, with the standard saying if you
do this, you get some kind of undefined behavior. However, I am not a
super-guru yet, therefore the posting here asking for either confirmation or
an explanation.

I've enclosed a sample program that shows both correct and incorrect
behavior. In the distro that gives me errors, if I wait until after the
object has been constructed and call pthread_create from some other method
(like 'thread.start()') then everything works ok, as the this pointer now
has a good virtual method table or something.

The command line command I use to compile this program is:
g++ -o junk junk.cpp -lpthread

It builds in linux or in cygwin. Does not work right in my version of
cygwin either, except no 'pure virtual method called' run-time error.

Thanks in advance for all the help.

Steve
#include <iostream>
#include <iomanip>
#include <pthread.h>
#include <unistd.h>

using namespace std;

class BaseThread {
public:
BaseThread() : started(false) { start(); }
virtual ~BaseThread() { }
void start() {
if (!started) {
started=true;
pthread_create(&id, NULL, BaseThread::hook, this);
}
}
private:
BaseThread& operator=(const BaseThread& val) { }
bool started;
pthread_t id;
virtual void* execute() = 0;
static void* hook(void* b) {
BaseThread* base = (BaseThread*)b;
return base->execute();
}
};

class Thread : virtual public BaseThread {
public:
Thread(bool start=false) : BaseThread() {
// if(start) this->start();
}
virtual ~Thread() { }
private:
Thread& operator=(const Thread& val) { }
virtual void* execute() {
cout << "Child::run" << endl;
return (void*)0;
}
};

class OtherBaseThread {
public:
OtherBaseThread() : started(false) { }
virtual ~OtherBaseThread() { }
void start() {
if (!started) {
started=true;
pthread_create(&id, NULL, OtherBaseThread::hook, this);
}
}
private:
OtherBaseThread& operator=(const OtherBaseThread& val) { }
bool started;
pthread_t id;
virtual void* execute() = 0;
static void* hook(void* b) {
OtherBaseThread* base = (OtherBaseThread*)b;
return base->execute();
}
};

class OtherThread : public OtherBaseThread {
public:
OtherThread(bool start=true) : OtherBaseThread() {
if(start) this->start();
}
virtual ~OtherThread() { }
private:
OtherThread& operator=(const OtherThread& val) { }
virtual void* execute() {
cout << "Child::run" << endl;
return (void*)0;
}
};

int main() {
OtherThread otherThread;
sleep(1);
Thread thread;
sleep(1);
return -1;
}
Jul 19 '05 #1
3 6670
Savagesmc wrote:

[...]
Problem Statement:
The problem I am experiencing is that in a fairly new distro of linux
(mandrake 9.1) calling pthread_create from the base class's constructor
(with this as a parameter) results in a 'pure virtual method called'
run-time error. However, in an older linux distro (redhat 7.3) everything
works as expected.

[...]

Virtual methods lose their virtual-ness property in a constructor (and a
destructor). The rationale is that the derived part of the object is
not fully constructed yet.

You'll need to call the "executive" function after the constructor is
completed.

Jul 19 '05 #2
"NFish" <no****@nowhere.net> wrote in message
news:BB*****************@newssvr25.news.prodigy.co m...

Virtual methods lose their virtual-ness property in a constructor (and a
destructor). The rationale is that the derived part of the object is
not fully constructed yet.

You'll need to call the "executive" function after the constructor is
completed.

First of all, thank you for taking the time to take a look at my problem. I
know
it probably isn't the easiest code to look at.

However, I do not beleive your statement above is correct, at least for the
destructor
part. Virtual methods must work in a destructor, as all good programming
(Meyers, etc...) books say to always make the destructor itself virtual.

That said, I don't think the issue here is a problem with virtual methods,
it's a problem
with the 'this' pointer. It seems to be a pointer to an object of the base
class's type during
the base class's constructor (which is called from the derived class's
constructor.) This
is also confirmed by the fact that calling pthread create in the derived
class's
CONSTRUCTOR (rather than the base class's constructor) does indeed work.
This doesn't seem like the correct behavior. The 'this' pointer should
always be to the
correct type, shouldn't it?

One of the best c++ programmers I know uses this same exact technique on the
g++,
MS C++, and Borland compilers. Until this Mandrake 9.1 build I am using, it
has worked on all of them - including g++.

My theory, the more I think about it, is that something is broken in the g++
I am using. -
Unless some smart person on here can convince me otherwise.
Jul 19 '05 #3
I consulted with my expert here, and it turns out that the 'this' pointer
points to the base class's VMT during the base constructor part of the
derived constructor. The VMT is not reliably set to the correct table until
after the derived constructor has finished. Therefore the pthread_create
must defer use of the 'this' pointer until after construction. There are a
number of ways this can be accomplished, particularly with the use of
semaphores.

Thank you for your help.
Jul 19 '05 #4

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

18
by: Ken | last post by:
Hi. Can anyone refer me to any articles about the compatibility between c++ polymorphism and real-time programming? I'm currently on a real-time c++ project, and we're having a discussion...
5
by: Arnd Schroeter | last post by:
Hello! I am a c++ programmer under the os linux. I am using pthreads and i am wondering why i can only use satic methods of a class to create a thread of it. How can i change this, because it...
15
by: John David Ratliff | last post by:
Maybe someone here can help me. I want to use C++, but pthreads seems to be nonfunctional in it. The following test code I've written in C and C++. The C version works, while the C++ one does...
4
by: Leslaw Bieniasz | last post by:
Cracow, 20.09.2004 Hello, I need to implement a library containing a hierarchy of classes together with some binary operations on objects. To fix attention, let me assume that it is a...
5
by: Parahat Melayev | last post by:
I am trying to writa a multi-client & multi-threaded TCP server. There is a thread pool. Each thread in the pool will handle requests of multiple clients. But here I have a problem. I find a...
2
by: um | last post by:
When the POSIX pthreads library for w32 release 2-2-0 (http://sources.redhat.com/pthreads-win32/) is compiled with VC++6 then it compiles and passes all the benchmark tests in the subdirectory...
5
by: Ed L. | last post by:
Is this pthreads warning of any concern? gcc -O2 -fno-strict-aliasing -Wall -Wmissing-prototypes -Wmissing-declarations -pthread -pthreads -D_REENTRANT -D_THREAD_SAFE -D_POSIX_PTHREAD_SEMANTICS...
8
by: Matt England | last post by:
My team currently using Boost Threads, but we are considering switching to ZThreads. (We seek cross-platform, C++ multithreading capabilities in an external library.) ZThread(s): ...
7
by: desktop | last post by:
This page: http://www.eptacom.net/pubblicazioni/pub_eng/mdisp.html start with the line: "Virtual functions allow polymorphism on a single argument". What does that exactly mean? I guess it...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.