multithreaded code being odd

Started by
3 comments, last by vaneger 20 years, 1 month ago

#include"mThread.h"
#include<fstream.h>
#include<limits.h>
#define THREAD_LIMIT 10
void main()
{
	unsigned int prgStart = GetTickCount();
	
	mThread *threads = new mThread[32];
	
	ofstream file;
	file.open("primesCount.txt",ios::out);

	threads[0].n = 1;
	threads[0].threadLimit = THREAD_LIMIT;
	threads[0].threadID = 0;
	threads[0].fileName ="primes0.txt";
	threads[0].numPrimes = 0;
	for(int q = 1;q < 32;q++)
	{
		threads[q].numPrimes = 0;
		threads[q].n = THREAD_LIMIT * (q);
		if(threads[q].n % 2 == 0)
			threads[q].n+=1;
		if(threads[q].n == threads[q-1].threadLimit)
			threads[q].n += 2;
		threads[q].threadLimit = THREAD_LIMIT * (q + 1);
		threads[q].threadID = q;
		switch(q)
		{
		case 1:threads[q].fileName ="primes1.txt";break;
		case 2:threads[q].fileName ="primes2.txt";break;
		case 3:threads[q].fileName ="primes3.txt";break;
		case 4:threads[q].fileName ="primes4.txt";break;
		case 5:threads[q].fileName ="primes5.txt";break;
		case 6:threads[q].fileName ="primes6.txt";break;
		case 7:threads[q].fileName ="primes7.txt";break;
		case 8:threads[q].fileName ="primes8.txt";break;
		case 9:threads[q].fileName ="primes9.txt";break;
		case 10:threads[q].fileName ="primes10.txt";break;
		case 11:threads[q].fileName ="primes11.txt";break;
		case 12:threads[q].fileName ="primes12.txt";break;
		case 13:threads[q].fileName ="primes13.txt";break;
		case 14:threads[q].fileName ="primes14.txt";break;
		case 15:threads[q].fileName ="primes15.txt";break;
		case 16:threads[q].fileName ="primes16.txt";break;
		case 17:threads[q].fileName ="primes17.txt";break;
		case 18:threads[q].fileName ="primes18.txt";break;
		case 19:threads[q].fileName ="primes19.txt";break;
		case 20:threads[q].fileName ="primes20.txt";break;
		case 21:threads[q].fileName ="primes21.txt";break;
		case 22:threads[q].fileName ="primes22.txt";break;
		case 23:threads[q].fileName ="primes23.txt";break;
		case 24:threads[q].fileName ="primes24.txt";break;
		case 25:threads[q].fileName ="primes25.txt";break;
		case 26:threads[q].fileName ="primes26.txt";break;
		case 27:threads[q].fileName ="primes27.txt";break;
		case 28:threads[q].fileName ="primes28.txt";break;
		case 29:threads[q].fileName ="primes29.txt";break;
		case 30:threads[q].fileName ="primes30.txt";break;
		case 31:threads[q].fileName ="primes31.txt";break;
		}
	}
	for(q = 0; q < 32;q++)
		threads[q].Begin();
	q--;
	for(q;q>=0;q--)
		threads[31].numPrimes += threads[q].numPrimes;

	file<<threads[31].numPrimes<<endl;
	file.close();
	cout.ios::precision(10);
	cout<<"process complete in "<<double((GetTickCount() - prgStart)/1000.0)<<" seconds" <<endl;

	
}

   
#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()
  {
	 SuspendThread(d_threadHandle);
  }
  void Res()
  {
	 ResumeThread(d_threadHandle);
  }
  bool IsRunning();

  virtual DWORD ThreadProc();
};

   
#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()
	{
		numPrimes++;
		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();
	}
	int numPrimes;
	ofstream fout;
	char *fileName;
	bool myPrime;
	unsigned long n;
	unsigned long threadLimit;
	int threadRunTime;
	int threadSetup;
	int threadID;
};


   
#pragma once
#ifndef mthread_H_
#include"mThread.h"
#endif
mThread::mThread()
{
	threadSetup = INI_THREAD;
	threadLimit = 4294967293;
	n = 1;
	threadRunTime = 100;
}
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()
{
	unsigned int startTime = GetTickCount();
	RESET:
	/*
	if(GetTickCount() - startTime >= threadRunTime)
	{
		cout<<"thread:"<<threadID<<" "<<"suspending execution"<<endl;
		
		Sus();
	}
	Sleep(1);*/
	switch(threadSetup)
	{
		case INI_THREAD: 
								n+=2;
								threadSetup = START_THREAD;
								break;
		case START_THREAD:
								if(n % 2 == 1)
									myPrime = this->isPrime();
								else
									myPrime = false;
								if(myPrime)
									threadSetup = REPORT_THREAD;
								else
								{
									threadSetup = INI_THREAD;
								}
								break;
								
		case REPORT_THREAD:
								report();
								if(threadSetup != KILL_THREAD)
									threadSetup = INI_THREAD;
								break;
		case KILL_THREAD: 
								End();
								break;
	}
	if(threadSetup != KILL_THREAD)
		goto RESET;
  return 0;
}
it finds too many primes in the test set. (ie 84 are found in 1 - 320). im not sure what i do wrong though can any one help?
Advertisement
Dood you''re code is WAY longer than it should be.
Try using things like:

threads[q].fileName = printf("primes%d.txt", q) ;

to get rid of the switch statement.
Try to get rid of your thread[0].xxxx statements as you should be able to make it the same for every case. Make it part of the loop.

This part has a bug in it:
q--;
for(q;q>=0;q--)
threads[31].numPrimes += threads[q].numPrimes;
The first iteration starts at 31. I assume you don''t mean to add item 31 to item 31 to begin with?! I suggest using a temporary instead of one of the array items. Also it''s bad practice to start the for last for loop above the way you do. make it say q=31 so that it is obvious.

What gives your threads time to do anything between the Begin line and the adding up of the numPrimes? Something is missing there.

Your isPrime function should start at 2, not 3 and must step by 1 not 2. That is another reason why you have too many found.

I hope this doesn''t sound too flamey. Its just that I had to fix code like this I''d start over from scratch.

think ... plan ... code
"In order to understand recursion, you must first understand recursion."
My website dedicated to sorting algorithms
well, the printf thing doesnt work, i knew about the for loop bug and have since fixed it, though i avoided it cus i knew it was only off by threads[31].numPrimes which only accounts for 1 when testing 320 numbers, and thus irrelevant.

the isPrime function for one is never passed even numbers and i dont need to worry about 2 being prime i know its prime, and for two starting it at 3 and adding 2 means im only testing odd numbers since all even numbers dont need to be tested at all.

and as for the lettign the code work after the Begin to before the adding of numPrimes, it seems to work but just in case what do you suggest i do to allow that ?
fstream.h is deprecated, use fstream (no .h) and the std namespace.

You shouldn''t start programming (in C++ or otherwise) with multi-threaded code. Write a single-threaded version that works flirst.

- The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara
fstream compared to fstream.h causes errors so i switched to .h thats why i use that. i already coded a simple for loop that calls isPrime X times, so i know that works. this is not my first attempt at programming or something :-\ i am asking how to fix the code i have not to be lectured on "oh try something simpler first" or" your code looks ugly" i know both of those things, ive been programming since i was 9.

so could i please get some responses as to what is causes this code to count too many prime numbers?

This topic is closed to new replies.

Advertisement