Archived

This topic is now archived and is closed to further replies.

vaneger

threaded code not making threads

Recommended Posts

#pragma once
#define WINDOWS_LEAN_AND_MEAN
#include <windows.h>

class cThread
{
protected:
  HANDLE  d_threadHandle;
  DWORD   d_threadID;
  bool    d_bIsRunning;

public:
  cThread();
  virtual ~cThread();

  void Begin();
  void End();
  bool IsRunning();

  virtual DWORD ThreadProc();
};
#include"cThread.h"
#ifndef _WIN32
#define _WIN32 
#endif
#ifndef _MT
#define _MT
#endif 
#include<iostream.h>
cThread::cThread()
{
  d_threadID = 0;
  d_threadHandle = NULL;
  d_bIsRunning = false;
}
cThread::~cThread()
{
  End();
}
DWORD cThread::ThreadProc()
{
	 return 0;
}
static DWORD WINAPI cThreadProc( cThread *pThis )
{
	return pThis->ThreadProc();
}
void cThread::Begin()
{
#if defined( _WIN32 ) && defined( _MT )
  if( d_threadHandle )
    End();  // just to be safe.


  // Start the thread.

  d_threadHandle = CreateThread( NULL,
                                 0,
                                 (LPTHREAD_START_ROUTINE)cThreadProc(this),
                                 this,
                                 0,
                                 (LPDWORD)&d_threadID );
  if( d_threadHandle == NULL )
  {
	  
    // Arrooga! Dive, dive!  And deal with the error, too!

  }
  d_bIsRunning = true;
#endif
}


void cThread::End()
{
#if defined( _WIN32 ) && defined( _MT )
  if( d_threadHandle != NULL )
  {
    d_bIsRunning = false;
    WaitForSingleObject( d_threadHandle, INFINITE );
    CloseHandle( d_threadHandle );
    d_threadHandle = NULL;
  }
#endif
}
bool cThread::IsRunning()
{
	return(d_bIsRunning);
}
#pragma once
#ifndef mthread_H_
#define mthread_H_

#include"cThread.h"
#include<fstream.h>
#include<math.h>

#define KILL_THREAD 0
#define START_THREAD 1
#define INI_THREAD 2
#define REPORT_THREAD 3

class mThread : public cThread
{
public:
	mThread();
	~mThread();
	DWORD ThreadProc();
	inline bool isPrime();
	inline void report()
	{
		fout.open(fileName,ios::app);
		fout<<n<<endl;;
		fout.close();
		check_limit();
	}
	inline void request_kill()
	{
		threadSetup = KILL_THREAD;
	}
	inline void check_limit()
	{
		if(n >= threadLimit)
			request_kill();
	}
	ofstream fout;
	char *fileName;
	bool myPrime;
	unsigned long n;
	unsigned long threadLimit;
	int threadSetup;
	int threadID;
};

#endif
#pragma once
#include"mThread.h"

mThread::mThread()
{
	threadSetup = INI_THREAD;
	threadLimit = 4294967293;
	n = 1;
}
inline bool mThread::isPrime()
{
	unsigned long sqr = sqrt(n);
	for (unsigned long x = 3; (x  <= sqr); x +=2)
		if(n % x == 0)
			return false;
	return true;
}
mThread::~mThread()
{
	End();
}
DWORD mThread::ThreadProc()
{
	RESET:
	switch(threadSetup)
	{
		case INI_THREAD: 
								n+=2;
								threadSetup = START_THREAD;
		case START_THREAD:
								myPrime = this->isPrime();
								if(myPrime)
									threadSetup = REPORT_THREAD;
								else
								{
									threadSetup = INI_THREAD;
									goto RESET;
								}
		case REPORT_THREAD:
								report();
								if(threadSetup != KILL_THREAD)
									threadSetup = INI_THREAD;
								goto RESET;
		case KILL_THREAD: 
								End();
	}
  return 0;
}
#include"mThread.h"
void main()
{
mThread *threads = new mThread[32];
	
	threads[0].n = 1;
	threads[0].threadLimit = 1000;
	threads[0].threadID = 0;
	threads[0].fileName ="primes0.txt";
	threads[0].Begin();
	
	for(int q = 1;q < 32;q++)
	{
		threads[q].n = threads[q - 1].n;
		threads[q].threadLimit = threads[q - 1].threadLimit * (q + 1);
		threads[q].threadID = q;
		switch(q)
		{
		case 1:threads[q].fileName ="primes1.txt";
		case 2:threads[q].fileName ="primes2.txt";
		case 3:threads[q].fileName ="primes3.txt";
		case 4:threads[q].fileName ="primes4.txt";
		case 5:threads[q].fileName ="primes5.txt";
		case 6:threads[q].fileName ="primes6.txt";
		case 7:threads[q].fileName ="primes7.txt";
		case 8:threads[q].fileName ="primes8.txt";
		case 9:threads[q].fileName ="primes9.txt";
		case 10:threads[q].fileName ="primes10.txt";
		case 11:threads[q].fileName ="primes11.txt";
		case 12:threads[q].fileName ="primes12.txt";
		case 13:threads[q].fileName ="primes13.txt";
		case 14:threads[q].fileName ="primes14.txt";
		case 15:threads[q].fileName ="primes15.txt";
		case 16:threads[q].fileName ="primes16.txt";
		case 17:threads[q].fileName ="primes17.txt";
		case 18:threads[q].fileName ="primes18.txt";
		case 19:threads[q].fileName ="primes19.txt";
		case 20:threads[q].fileName ="primes20.txt";
		case 21:threads[q].fileName ="primes21.txt";
		case 22:threads[q].fileName ="primes22.txt";
		case 23:threads[q].fileName ="primes23.txt";
		case 24:threads[q].fileName ="primes24.txt";
		case 25:threads[q].fileName ="primes25.txt";
		case 26:threads[q].fileName ="primes26.txt";
		case 27:threads[q].fileName ="primes27.txt";
		case 28:threads[q].fileName ="primes28.txt";
		case 29:threads[q].fileName ="primes29.txt";
		case 30:threads[q].fileName ="primes30.txt";
		case 31:threads[q].fileName ="primes31.txt";
		
		}
		threads[q].fout<<"thread ID "<<threads[q].threadID<<endl;
		threads[q].Begin();
	
	}
	
}

the file only outputs to 2 files primes0.txt and primes31.txt which indicates that it doesnt seem to create all of the threads and when i use a process viewer it only shows one thread running :-\ what did i do wrong?

Share this post


Link to post
Share on other sites
are you compiling with a /MT switch and linking against the Multi-threaded runtime library? if you're not it won't run multi-threaded

-me

[edited by - Palidine on March 18, 2004 7:51:21 PM]

Share this post


Link to post
Share on other sites

libcimtd.lib(ofstream.obj) : error LNK2001: unresolved external symbol "void * __cdecl operator new(unsigned int,int,char const *,int)" (??2@YAPAXIHPBDH@Z)
libcimtd.lib(filebuf1.obj) : error LNK2001: unresolved external symbol "void * __cdecl operator new(unsigned int,int,char const *,int)" (??2@YAPAXIHPBDH@Z)
libcimtd.lib(streamb.obj) : error LNK2001: unresolved external symbol "void * __cdecl operator new(unsigned int,int,char const *,int)" (??2@YAPAXIHPBDH@Z)
Debug/threaddriver.exe : fatal error LNK1120: 1 unresolved externals


its being weird when i compile and link with a /MT switch, although i do have it linked to a debug multithreaded dll ( chosen from code generation in project settings->link.

Share this post


Link to post
Share on other sites
it runs and compiles if i use debug MT but not MT. it still wont seem to run the threads though. is it perhaps because of the way i setup the threads array as

mThread *threads = new threads[32];

do i have to store the threads differntly, is it accidently only making one thread because i only have one pointer?

Share this post


Link to post
Share on other sites
... that part of it should be ok; you're simply making space for 32 mThreads.

I don't know your threading library well enough to help you there. But I will point out that that case statement is ugly as sin. Try using string concatenation (via a stringstream) to create the filename, instead.

Edit>> LOL, I was on the right track and didn't even notice. Good catch, mattd.

[edited by - Zahlman on March 19, 2004 11:24:25 AM]

Share this post


Link to post
Share on other sites
Hehe, you've forgotten to end each case with a break, so it always ends up setting "primes31.txt" as the filename for all but the first thread.


case 1:threads[q].fileName ="primes1.txt";
case 2:threads[q].fileName ="primes2.txt";
case 3:threads[q].fileName ="primes3.txt";
// ...
case 30:threads[q].fileName ="primes30.txt";
case 31:threads[q].fileName ="primes31.txt";

Add break; statements after the filename string.

EDIT: It looks like you don't know about break. If you do this:

switch(a)
{
case 1: printf("a = 1\n");
case 2: printf("a = 2\n");
};

If a is 1, it will print "a = 1" AND THEN CONTINUE to print "a = 2". You need to tell it when to get out of the switch statement by doing:

switch(a)
{
case 1: printf("a = 1\n"); break;
case 2: printf("a = 2\n"); break;
};


____________
ride the sainted rhythms on the midnight train to romford

[edited by - mattd on March 19, 2004 5:26:36 AM]

Share this post


Link to post
Share on other sites
hmm i thought you only had to use break if you changed the variable that is being switched off of during the case statement as ian duff''s device? is it really mandatory?

Share this post


Link to post
Share on other sites
break tells it when to stop in the switch block. yes you need to use it every time. the reason that is so is so you can do things like this


switch(foo)
{
case FIRE_THEN_MOVE:
DoFireAction();
case MOVE:
DoMoveAction();
break;
}


that way FIRE_THEN_MOVE can use the code already existing for the move action without having to rewrite it all. this is a simple example for which a switch really doesn''t help all that much but i''m sure you get the idea.

-me

Share this post


Link to post
Share on other sites
ok soi got it up and running, but do i have to manually suspend and resume the threads and if so how should i do that (ie what timer functions and function calls)?

Share this post


Link to post
Share on other sites

#pragma once
#define WINDOWS_LEAN_AND_MEAN
#include <windows.h>

class cThread
{
protected:
HANDLE d_threadHandle;
DWORD d_threadID;
bool d_bIsRunning;

public:
cThread();
virtual ~cThread();

void Begin();
void End();
void Sus()
{
d_threadHandle.SuspendThread();
}
void Res()
{
d_threadHandle.ResumeThread();
}
bool IsRunning();

virtual DWORD ThreadProc();
};

this method of suspending and resuming doesnt compile, how do i need to change this for it to work?

Share this post


Link to post
Share on other sites