Click here to Skip to main content
15,892,746 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
Recently I have posted a question with regard to multithreading inside my class MC_Simulation. My problem was the access to class information from the static thread function. This problem is solved apparently by using the pointer to ‘this’ in the argument, which was transferred to the threading function.

C++
// define the Thread Data Structure to be transferred to the (static) thread function
// --------------------------
typedef struct Thread_Data{
	MC_Simulation*	mc_simulation;	// this solved my initial problem
	long  first_scenario;
	long  last_scenario;
	char  bond_data_file[_MAX_FNAME];	
} THREAD_DATA, *PTHREAD_DATA;

My problems with the tread function unfortunately are not yet finalized.
Two issues have shown up.

1) My thread function is supposed to write calculated results using

C++
ofstream bond_data;
bond_data.open(FILE_NAME, ios::trunc);
// in between calculating some stuff
    // then output results
    bond_data <<  results << EL;
    bond_data.close();

this does not seem to work properly. Do I have to use fprinf(..) instead?

2) It also seems that some other issues have not been dealt with properly such as synchronization of threads, which has been explicitly addressed earlier. I am not fully aware how to do that. Please have a look at the structure:

C++
// -----------------------------------
// member function in MC_Simulation:

Void initiate_threads(void){

int 		scenario_range[MAX_THREADS+1];
HANDLE		hThread[MAX_THREADS]; 
DWORD		dwThreadID[MAX_THREADS];
PTHREAD_DATA	pthread_arg[MAX_THREADS];

/* initiate  threads, each thread is supposed to run a loop starting with first_scenario and ending with last_scenario and there are 10,000 scenarios in total */
for (int index=0; index<max_threads;index++){>

        // allocate memory
        pthread_arg[index] =	(PTHREAD_DATA) HeapAlloc(GetProcessHeap(), 
                                                 HEAP_ZERO_MEMORY,
                				 sizeof(THREAD_DATA));
	// fill the argument of thread function
	pthread_arg[index]->first_scenario = scenario_range[index];
	pthread_arg[index]->last_scenario  = scenario_range[index+1];		pthread_arg[index]->mc_simulation  = this;
        sprintf(pthread_arg[index]->bond_data_file,"%s_%d",bond_data_file,index);

        hThread[index] = CreateThread(NULL, 0, thread_function ,
                                      pthread_arg[index], 0, &dwThreadID[index]);		
	} // end for loop

	 // Wait until all threads have terminated.
       	WaitForMultipleObjects(MAX_THREADS, hThread, TRUE, INFINITE);

	  for(int i=0; i < MAX_THREADS; i++) {
			CloseHandle(hThread[i]);
			if(pthread_arg[i] != NULL){
	 			HeapFree(GetProcessHeap(), 0, pthread_arg[i]);
	 		pthread_arg[i] = NULL;}    // Ensure address is not reused.
	  } // end for loop

} // end thread calling function

I am not sure whether I have taken account of all important issues properly, such as synchronization of the threads. The routine is not performing as expected. “thread_function” on its own is a nested loop across the interval of scenarios as defined in pthread_arg[index], then across the periods within a simulation path, and finally across the bonds of a fixed income portfolio. “Scenario” and “Bond” are separate classes and calling simultaneously functions of a linked in library. What do I have to change or do I expect too much from multithreading anyway?
Posted
Updated 23-Oct-12 10:56am
v2
Comments
Chuck O'Toole 23-Oct-12 18:55pm    
What the difference between "MAX_THREADS" and "max_threads"? You use both in this code.
haraldhubbes 28-Oct-12 16:11pm    
MAX_THREADS is global integer denoting the number of threads to be called and max_threadsn is a typo and should read MAX_THREADS.

ofstream bond_data;
bond_data.open(FILE_NAME, ios::trunc);
// in between calculating some stuff
// then output results
bond_data <<  results << EL;
bond_data.close();

I assume FILE_NAME is a constant, in which case you are truncating and writing to the same file from multiple threads concurently - that doesn't sound like a good idea.

Perhaps you meant to use the bond_data_file member of the Thread_Data structure?

Best regards
Espen Harlinn
 
Share this answer
 
Comments
Sergey Alexandrovich Kryukov 25-Oct-12 14:50pm    
A 5.
--SA
Espen Harlinn 25-Oct-12 16:05pm    
Thank you, Sergey :-D
I don't know what you mean by, "this does not seem to work properly". Stream operators work just fine in threads. Allocating pthread memory is a bit complicated. Look up semaphores, events, multithreaded queues, thread locking etc... When you create a thread, you can pass it a (void *). Pass the class instance here, and you can associate one class for each thread. Then in your thread, cast that (void *) back to the class type and call methods in the class.
 
Share this answer
 
C++
ofstream bond_data;
bond_data.open(pThreadArg->bond_data_file, ios::trunc);
// in between calculating some stuff
// then output results
bond_data <<  results << EL;
bond_data.close();

Here FILE_NAME is changed to bond_data_file, therefore separate files will be created for each threads.

C++
sprintf(pthread_arg[index]->bond_data_file,"%s_%d",bond_data_file,index);

bond_data_file should be assigned starting of output file name.

I am not sure whether I have taken account of all important issues properly, such as synchronization of the threads.

Make sure thread_func is not updating any parameters in the class. Since we are passing this pointer(as mc_simulation parameter of the structure) to threads. If more than one thread updating any parameter of the class, it will create access violation or improper results.

The routine is not performing as expected.

What are the problems? If your machine is single core processor then you will not get a better performance.
If input of one thread is depend on the output of other threads, then you will not get the expected output. Please make sure processing of a single thread is independent, ie, none of these thread require an output from other thread. For example, Port Folio calculation of thread_N is started from first_calculation to last_calculation, and it should not depend on the Port Folio calculation of any thread.
 
Share this answer
 
Comments
haraldhubbes 28-Oct-12 17:04pm    
None of the above listed problems applies, as my processor has 12 cores, the threads can work independently and do not change any information of the class. Each thread is writing its calculated results into a separate file. The programm is not working properly in the sense that in the course of running it appears at a sudden to be stuck in one thread for a while and then again it continues the execution. Apparently there is a command missing which ensures a smooth execution accross the threads.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900