Click here to Skip to main content
15,890,512 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I have to create an application where I'll have to make multiple threads. SoI thought to try making one function and passing it to different threads. Initially I've created two threads and have declared one function to be passed to both of them. All I am trying to do is to pass different integers to those threads and display it in the thread function,here is my code:
DWORD WINAPI Name(LPVOID lpParam)
           {
         int *Ptr=(int*)lpParam;

         for(int j=0;j<2;j++)
              {
              cout<<"Thread"<<endl;
              cout<<*Ptr<<endl;
              }

            return 0;
           }
            int main()
            {


            int a=10,b=15,c=25;
           HANDLE thread1,thread2;
           DWORD threadID,threadID2;
           thread2= CreateThread(NULL,0,Name,LPVOID(a),0,&threadID2);
           thread1= CreateThread(NULL,0,Name,LPVOID(b),0,&threadID);


         for(int i=0;i<5;i++)
          {
           cout<<"Main Thread"<<endl;
          }

          if(thread1==NULL)
            {
           cout<<"Couldn't Create Thread:("<<endl;
           exit(0);
           }
             if(thread2==NULL)
            {
           cout<<"Couldn't Create Thread:("<<endl;
           exit(0);
            }
                  return 0;
             }


but this code is not running properly,i.e compliles fine,starts fine but afterwards gives a debugging error. Could someone let let me know of my mistake and how I could correct it coz being able to utilize one function for multiple threads will be really helpful for me.
Posted

You are passing the thread parameters by value by casting int to LPVOID. That is the correct way because the variables are local.

But in your thread function, you are accessing them as pointers. You must do it there in a similar way by just casting the LPVOID to int:
C++
int iParam = (int)lpParam;
for(int j=0;j<2;j++)
{
    cout<<"Thread"<<endl;
    cout<<iParam<<endl;
}
 
Share this answer
 
Comments
Aayman Khalid 2-May-13 6:53am    
Thank you so much:)I guess I haven't been able to understand dereferencing properly,coz uptil now I used to assign values to a pointer like this"int *P=x".
Could you explain to me how this happened,I will be really thankful...
Jochen Arndt 2-May-13 7:26am    
LPVOID is often (and here) used to provide a parameter of unspecified type. It is up to you how to use it and ensure that you get the correct value on the 'receiving' side.

But the solution is simple: Cast to those type that has been passed (the type itself or a pointer when passing a pointer) and ensure that the casted type fits. Fitting is no problem when using pointers or types with smaller or equal size (like int, unsigned, char).

But when using pointers, you must ensure that the variable itself still exists when it is accessed. This is very important with threads. Such variables should be global or class members (with class members, the class must exists while the thread is running).

Examples:

// Using static variables
static int iParam1 = 1;
static char str1[128] = "test";
CreateThread(NULL, 0, Name, (LPVOID)&iParam1, 0, &ID);
CreateThread(NULL, 0, Name, (LPVOID)str1, 0, &ID);

// Using class members
// In the header file int m_iParam2, LPSTR m_lpszStr;
m_iParam2 = 2;
m_lpszStr = new char[128];
strcpy(m_lpszStr, "Test");
CreateThread(NULL, 0, Name, (LPVOID)&iParam2, 0, &ID);
CreateThread(NULL, 0, Name, (LPVOID)m_lpszStr, 0, &ID);
// Ensure that thread has terminated before deleting the string
// and the class still exists.

In both above cases, access the parameters by casting to int* and LPSTR (or LPCSTR if it is not changed):
// lpParam is ptr to int
int *pParam = (int *)lpParam;
// get value from above pointer
int iParam1 = *pParam;
// get value from passed parameter
int iParam2 = *((int *)lpParam);

LPSTR lpszStr = (LPSTR)lpParam;
// When not changing the string, const should be used
LPCSTR lpszStrC = (LPCSTR)lpParam;

I hope this answers your questions.
Aayman Khalid 2-May-13 7:46am    
One more thing: does type casting return some value(for different data types or any value at all),e.g if two threads are utilising one function but the argument of one thread is an integer and that of the other function is a string,then I have to take a descision based on the type casting,so is it possible???
Jochen Arndt 2-May-13 8:04am    
Type casting tells the compiler that he should treat the value on the right side as another type so that it can be assigned to the variable on the left side. Without casting, the compiler throws an error.

In special cases casting changes the value (e.g. when casting a double to an int where the fractional digits are cut off or cutting of high bits when the left side has less bits than the right). But with pointers and integers, the value itself is unchanged but used in a different way.

In your original code, you passed the integers by value (10 and 15) and casted them to pointers to int. That means that you had two pointers with value 10 and 15. When then accessing the data of these pointers (printing them with cout), the memory at the addresses 10 and 15 is read.

Knowing this, it should be clear that you can't pass different types to one function this way. The common way to pass different types when only one parameter is available, is the usage of structures containing a member that identifies the type of the passed data and other members that contain the data.
Aayman Khalid 2-May-13 6:55am    
and also,will it work if I pass srings or character arrays to it???
C++
LPVOID(a) -> &a
LPVOID(b) -> &b

Remove the unused c variable.
Before return 0; in your main function you should call:
C++
WaitForSingleObject(thread1, INFINITE);
WaitForSingleObject(thread2, INFINITE);

To prevent your program exiting before the threads finish.
 
Share this answer
 
Comments
Aayman Khalid 2-May-13 6:55am    
Thank you,pasztorpisti:)
pasztorpisti 2-May-13 7:02am    
You are welcome!
Aayman Khalid 2-May-13 7:12am    
And could you guide me what should I do if want to pass a string or an array to the thread please...
pasztorpisti 2-May-13 7:17am    
There are many ways but as you are a beginner I would recommend the following: Allocate memory for your data dynamically with new, pass the stuff as a pointer to your thread and delete the allocated storage by the thread. Example:
int* p = new int[10];
You simply pass p as the thread parameter and in your thread function you cast it back to int* and then use it. When you are done you execute delete [] p; in your thread function. You can pass a string similarly as a string is nothing more than an array of characters.
Aayman Khalid 2-May-13 7:34am    
Thanks a lot:)

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