Jump to content


_beginthread question


2 replies to this topic

#1 freezzo

    New Member

  • Members
  • PipPip
  • 30 posts

Posted 02 November 2007 - 01:58 PM

I'm trying to build a thread manager, which will basically figure out the number of processors available, and split work load up onto separate threads and im running into a problem of getting _beginthread to take the function i want:

#include <process.h>
#include <vector>
using namespace std;

class Threadable
{
public:
	Threadable()
	{
		is_multithreaded = true;
	}
	virtual void run() = 0;

	bool is_multithreaded;
};

class ThreadManager
{
public:
	void Add(Threadable *obj)
	{
		list.push_back(obj);
	}

	void Execute()
	{
		std::vector<Threadable *>::const_iterator i;

		for(i = list.begin(); i != list.end(); ++i)
		{
			(*i)->is_multithreaded = true;
			(*i)->run();
			_beginthread((*i)->run(), 0, 0);
		}
	}

	vector<Threadable *> list;
};

class Test: public Threadable
{
public:
	void run()
	{
		printf("hi\n");

		if(is_multithreaded)
			_endthread();
	}
};

void main(void)
{
	ThreadManager *thMan = new ThreadManager();
	Test *test = new Test();
	Test *test2 = new Test();

	thMan->Add(test);
	thMan->Add(test);

	thMan->Execute();
}

The logic isnt in yet to split up workload, just trying to pass it to beginthread. Any ideas what I am doing wrong?

I added all the code here, its actually in separate class files. Here is my error:

c:\test\input_handler\thread_manager.h(33) : error C2664: '_beginthread' : cannot convert parameter 1 from 'void' to 'void (__cdecl *)(void *)'

I have used _beginthread before with normal functions, I Just cant figure out how to use it with a function referenced from a class stored in the vector.

Thanks

#2 .oisyn

    DevMaster Staff

  • Moderators
  • 1810 posts

Posted 02 November 2007 - 02:27 PM

_beginthread((*i)->run(), 0, 0);
You're calling the function run() on *i, and are using the result from that function to pass to _beginthread(). Compare:
int a()
{
    return 123;
}

void b(int i)
{
    std::cout << i << std::endl;
}

int main()
{
    b(a());
}
Do you pass the function a to b? No, you pass the result from a() to b, so b gets called with the int 123.

What you need is a pointer to the appropriate function. Unfortunately, you will not be able to get the pointer as the run() method is an instance method and not static, so you can't get a pointer to it and just call it, because you don't know which object to call it on.

Fortunately, however, _beginthread() accepts an extra user parameter, which will be passed to the callable function in the other thread. If you pass the Threadable instance as user parameter, and use a global function to reroute the call to Run() on that instance, you'll be fine.

void CallRun(void * instance)
{
    static_cast<Threadable*>(instance)->Run();
}

void StartThread(Threadable * t)
{
    _beginthread(CallRun, 0, t);
}

C++ addict
-
Currently working on: the 3D engine for Tomb Raider.

#3 freezzo

    New Member

  • Members
  • PipPip
  • 30 posts

Posted 02 November 2007 - 02:53 PM

Thanks!

I can't believe I overlooked that fact. Total brain dump there.





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users