Multithreading MADNESS!!!

Started by
14 comments, last by anonuser 18 years, 8 months ago
So far, I'm no closer to where I was to start with. This can only mean that I need to do one thing: Post code!

Here's what I'm trying to do. I want a base class name CThreadKernel, which allows me to encapsulate (and ultimately forget about) the creation of a thread. The base class creates the thread and destroys it. This is an abstract class. Not implemented in the base class are OnInitialize(), OnExecute() and OnUninitialize(). I plan to extend this class for each of my threads. So here's the code... (Keep in mind, a lot of this is bad test code)

threadkernel.h
#ifndef __THREADKERNEL_INCLUDED__#define __THREADKERNEL_INCLUDED__#include "system.h"#include <process.h>#define THREADKERNEL_RET_OKAY		0#define THREADKERNEL_RET_ERROR		-1class CThreadKernel {public:						CThreadKernel ();						~CThreadKernel ();	void				SetDelay (int milliseconds);	BOOL				Execute ();	void				Kill ();	int					GetDelay ();	BOOL				IsActive ();	void				Thread ();protected:	virtual BOOL		OnInitialize () = 0;	virtual BOOL		OnExecute () = 0;	virtual BOOL		OnUninitialize () = 0;private:	volatile BOOL		active;	int					delay;};#endif


threadkernel.cpp
#include "threadkernel.h"CThreadKernel *temp = NULL;void Launch ();void ThreadProc (void *param);void Launch () {	_beginthread (ThreadProc, 0, NULL);}void ThreadProc (void *param) {	temp->Thread();}CThreadKernel::CThreadKernel () {	this->active = false;	this->delay = 0;}CThreadKernel::~CThreadKernel () {	if (this->active) {		this->Kill ();		Sleep (500);	}}void CThreadKernel::SetDelay (int milliseconds) {	this->delay = milliseconds;}BOOL CThreadKernel::Execute () {	if (!this->active) {		this->active = true;		if (this->OnInitialize ()) return THREADKERNEL_RET_ERROR;		temp = this;		Launch ();	}	else {		return THREADKERNEL_RET_ERROR;	}	return THREADKERNEL_RET_OKAY;}void CThreadKernel::Kill () {	this->active = false;}int CThreadKernel::GetDelay () {	return this->delay;}BOOL CThreadKernel::IsActive () {	return this->active;}void CThreadKernel::Thread () {	do {		if (this->OnExecute ()) this->active = false;		if (this->delay > 0) Sleep (this->delay);	} while (this->active);	this->OnUninitialize ();	_endthread ();}

I would like to think that I don't need the temp, ThreadProc and Launch variables/functions. But, like I said, this is all in testing. I've seen examples of this work in straight "C" but this is being very quirky.

This code, when used with multiple threads, only allows one thread to work. Creating a single thread works beautifully. Once you add another thread, the previous thread craps out.

[edit]
BTW, I should also mention that this is a purely OO Win32 app. Have I outgrown _beginthread?
Quit screwin' around! - Brock Samson
Advertisement
volatile
Quote:Original post by Mxz
volatile

AH-HA! It's like in the old DOS days when I'd write interrupts. But still, I'm not seeing why creating other threads would eliminate the thread before it. Still, this link shows me that I need to take better measures in declaring variables that are changed by other threads. +!
Quit screwin' around! - Brock Samson
Quote:Original post by Moe
Something else you might want to check out is the boost library. I had a thread a week or two ago about getting it working.


Quoted for truth. The Boost library contains the only type-safe threading support that I'm aware of (no need to cast to void* and back, and other such nasty tricks). That linked thread also happens to include an example created by myself.
Your class is a very basic pattern and is considered the wrong-way-to-do-it (TM).
Don't use virtual functions in a thread controller class. Use a function object or some way to delegate it to your logic (the actual code). Seperate the thread controller pattern from the thread application logic and avoid virtual functions
in the controller pattern. It doesn't work nicely in Windows.

Or use Boost::threads.


"It's such a useful tool for living in the city!"
Alright, you'll probably want to read a bit on static buffers. Which is the real killer in multithreading.

Say you have a pointer to a buffer. You enter a thread and start working on that thread, now another thread starts in the middle of your thread and starts working on the same buffer. The buffer is now in an unknown state.

How you create your thread isn't really this issue. I use whatever the OS gives me. Win32's case CreateThread. In unix or linux pthreads.

A bit of a personal note, windows by far has the best threading model out of modern OS's. Most of the Win32 API is thread safe by nature or has saftey features. Like Windows can only be accessed from the thread they are created in or you have to create the Window in a special way.

You may want to consider your use for multithreading. As you only benfit if the operations are able to parallel process.

This topic is closed to new replies.

Advertisement