Re :- Multiple threading.

hi,
I am new to multithreading in c++. i found a simple code on a site . i think i understood the essentials of multithreading after reading it but when i try to compile the source code which is :-

#include <windows.h> <WINDOWS.H>

#include <strsafe.h> <STRSAFE.H>

#include <stdio.h><STDIO.H>


#define BUF_SIZE 255

//------------------------------------------

// A function to Display the message

// indicating in which tread we are

//------------------------------------------

void DisplayMessage (HANDLE hScreen,
char *ThreadName, int Data, int Count)
{

STRSAFE_LPSTR msgBuf;
size_t cchStringSize;
DWORD dwChars;

// Print message using thread-safe functions.

StringCchPrintf(msgBuf, BUF_SIZE,
TEXT("Executing iteration %02d of %s"
" having data = %02d \n"),
Count, ThreadName, Data);
StringCchLength(msgBuf, BUF_SIZE, &cchStringSize);
WriteConsole(hScreen, msgBuf, cchStringSize,
&dwChars, NULL);
Sleep(1000);
}

//-------------------------------------------

// A function that represents Thread number 1

//-------------------------------------------

DWORD WINAPI Thread_no_1( LPVOID lpParam )
{

int Data = 0;
int count = 0;
HANDLE hStdout = NULL;

// Get Handle To screen.

// Else how will we print?

if( (hStdout =
GetStdHandle(STD_OUTPUT_HANDLE))
== INVALID_HANDLE_VALUE )
return 1;

// Cast the parameter to the correct

// data type passed by callee i.e main() in our case.

Data = *((int*)lpParam);

for (count = 0; count <= 4; count++ )
{
DisplayMessage (hStdout, "Thread_no_1", Data, count);
}

return 0;
}

//-------------------------------------------

// A function that represents Thread number 2

//-------------------------------------------

DWORD WINAPI Thread_no_2( LPVOID lpParam )
{

int Data = 0;
int count = 0;
HANDLE hStdout = NULL;

// Get Handle To screen. Else how will we print?

if( (hStdout =
GetStdHandle(STD_OUTPUT_HANDLE)) ==
INVALID_HANDLE_VALUE )
return 1;

// Cast the parameter to the correct

// data type passed by callee i.e main() in our case.

Data = *((int*)lpParam);

for (count = 0; count <= 7; count++ )
{
DisplayMessage (hStdout, "Thread_no_2", Data, count);
}

return 0;
}

//-------------------------------------------

// A function that represents Thread number 3

//-------------------------------------------

DWORD WINAPI Thread_no_3( LPVOID lpParam )
{
int Data = 0;
int count = 0;
HANDLE hStdout = NULL;

// Get Handle To screen. Else how will we print?

if( (hStdout =
GetStdHandle(STD_OUTPUT_HANDLE))
== INVALID_HANDLE_VALUE )
return 1;

// Cast the parameter to the correct

// data type passed by callee i.e main() in our case.

Data = *((int*)lpParam);

for (count = 0; count <= 10; count++ )
{
DisplayMessage (hStdout, "Thread_no_3", Data, count);
}

return 0;
}


void main()
{
// Data of Thread 1

int Data_Of_Thread_1 = 1;
// Data of Thread 2

int Data_Of_Thread_2 = 2;
// Data of Thread 3

int Data_Of_Thread_3 = 3;
// variable to hold handle of Thread 1

HANDLE Handle_Of_Thread_1 = 0;
// variable to hold handle of Thread 1

HANDLE Handle_Of_Thread_2 = 0;
// variable to hold handle of Thread 1

HANDLE Handle_Of_Thread_3 = 0;
// Aray to store thread handles

HANDLE Array_Of_Thread_Handles[3];

// Create thread 1.

Handle_Of_Thread_1 = CreateThread( NULL, 0,
Thread_no_1, &Data_Of_Thread_1, 0, NULL);
if ( Handle_Of_Thread_1 == NULL)
ExitProcess(Data_Of_Thread_1);

// Create thread 2.

Handle_Of_Thread_2 = CreateThread( NULL, 0,
Thread_no_2, &Data_Of_Thread_2, 0, NULL);
if ( Handle_Of_Thread_2 == NULL)
ExitProcess(Data_Of_Thread_2);

// Create thread 3.

Handle_Of_Thread_3 = CreateThread( NULL, 0,
Thread_no_3, &Data_Of_Thread_3, 0, NULL);
if ( Handle_Of_Thread_3 == NULL)
ExitProcess(Data_Of_Thread_3);


// Store Thread handles in Array of Thread

// Handles as per the requirement

// of WaitForMultipleObjects()

Array_Of_Thread_Handles[0] = Handle_Of_Thread_1;
Array_Of_Thread_Handles[1] = Handle_Of_Thread_2;
Array_Of_Thread_Handles[2] = Handle_Of_Thread_3;

// Wait until all threads have terminated.

WaitForMultipleObjects( 3,
Array_Of_Thread_Handles, TRUE, INFINITE);

printf("Since All threads executed"
" lets close their handles \n");

// Close all thread handles upon completion.

CloseHandle(Handle_Of_Thread_1);
CloseHandle(Handle_Of_Thread_2);
CloseHandle(Handle_Of_Thread_3);
}

then i get the following error:-

MSVCRTD.lib(crtexew.obj) : error LNK2019: unresolved external symbol _WinMain@16 referenced in function ___tmainCRTStartup
1>C:\Users\jolly\Documents\Visual Studio 2010\Projects\learning windows programming\Debug\learning windows programming.exe : fatal error LNK1120: 1 unresolved externals

i am using visual studio 2010.



What is wrong ???
Please help me.
Thanks in advance for any assistance offered.



@kbw :thanks for your help . But after changing to console I was getting this error message that

msg not initialized ( It is in DisplayMessage function .)
Since i am new I did not knew how to initialize it so i simply gave it 0 then also there were some run time errors.
What to do ??


@Computergeek01


Hi ,
yes i do realize that this is not a good example but i am farely new so i was ready to take up any example just so that it works.

For instance i had read that we should not use CreateThread instead _beginthread etc, but beginthread was not there in visual studio and i did not knew it's equivalent in it .
I would be very thankful if u help me in using MULTITHREADING.
closed account (S6k9GNh0)
1. Use code tags. Please.
2. Is there another thread? Why are you referring to Computergeek01?

EDIT: Do not make multiple threads.
Last edited on
@ computerquip: This is sort of a repost. I guess they made some changes and are giving it another go. I had made some comments because the code doesn't hold on to the Handles for the new threads nor does it actually wait for the threads to finish before exiting, instead it creates blank handles and then waits for them to exit? I honestly don't know WTF the author was thinking

@ OP: Do you know how to use a call back function? I recently made a class that may help you out if you're interested in seeing how simple threading can be.

EDIT: beginthread: http://msdn.microsoft.com/en-us/library/kdzttdcb.aspx
Last edited on
Simple Threading Example, NOTE: This is NOT the class I mentioned in my last post.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#include <iostream>
#include <fstream>
#include <vector>

#include <windows.h>
#include <winbase.h>

void pause() __attribute__((destructor)); //GCC Destructor
DWORD WINAPI MyThread(LPVOID);

std::vector<std::string> WordVec;

void pause()
{
    std::cin.sync();
    std::cin.ignore();
}

int main(int argc, char *argv[])
{
    std::ifstream InFile("Index.txt", std::ios_base::in); //Open External File To Read
    std::string MSG;
    
    while(InFile >> MSG) //Read From External File
        {WordVec.push_back(MSG);}
        
    int num = WordVec.size(); //Get Size For Arrays
    
    HANDLE ThreadArry[num]; //Thread Handle Array
    DWORD ThreadHndl[num];  //Thread ID Array
    
    SECURITY_ATTRIBUTES SA;
        SA.nLength = sizeof(SECURITY_ATTRIBUTES);
        SA.lpSecurityDescriptor = NULL;
        SA.bInheritHandle = TRUE;
    
    for(int i = 0; i < WordVec.size(); i++)
    {
        ThreadArry[i] = CreateThread(&SA, 0, &MyThread, (LPVOID) i, 0, &ThreadHndl[i]);
        
        if(ThreadArry[i] == NULL) /*Check If Thread Creation Failed*/
            {std::cout << GetLastError() << '\n';}
    }
    
    WaitForMultipleObjects(num, ThreadArry, TRUE, 20000); /*Use Thread Handle Array As Second Argument Here*/
    
    for(int i = 0; i < num; i++) /*Close Handles To Threads*/
    {
          std::cout << "\nClosing Handle " << i << '\n';
          CloseHandle(ThreadArry[i]);
     }
    
    InFile.close();
    return EXIT_SUCCESS;
}


DWORD MyThread(LPVOID Param)
{
    int i = (int) Param; //Data Must Be Recast
    
    //pause(); //Will Hold Each Thread Open For You To See In Process Explorer
    std::cout << WordVec[i] << '\n'; //Use Data Passed To Address Global Vector Index

    return (DWORD) i;
}
Last edited on
closed account (S6k9GNh0)
Or boost::thread (or std::thread) and boost::function work like none other.
Topic archived. No new replies allowed.