Thread: Multithreading with the Windows API

  1. #1
    Registered User Xzyx987X's Avatar
    Join Date
    Sep 2003
    Posts
    107

    Multithreading with the Windows API

    I am trying to create a multithreaded program using the windows API. Here is what I have so far:
    Code:
    //Definitions//////////////////////////////////////////////////////////////////////////////
    
    //Define this to allow multithreading
    
    #define _MT
    
    ///////////////////////////////////////////////////////////////////////////////////////////
    
    
    
    //Include files////////////////////////////////////////////////////////////////////////////
    
    #include <windows.h>
    #include <stdio.h>
    #include <commctrl.h>
    #include "resource.h"
    
    #include "diologs.h"
    
    ///////////////////////////////////////////////////////////////////////////////////////////
    
    
    
    //Global variables/////////////////////////////////////////////////////////////////////////
    
    //All puropose counter variable
    
    int      i;
    
    //Thread handles
    
    HANDLE mainDialogProc_Handle;  //Main diolog
    
    //Thread IDs
    
    LPDWORD mainDialogProc_ID;  //Main diolog
    
    
    ///////////////////////////////////////////////////////////////////////////////////////////
    
    
    
    //Main function. Serves as entry point for other application threads///////////////////////
    
    bool main(void)
    {
    
    	printf("%d\n",GetLastError());
    
    	mainDialogProc_Handle = CreateThread(
    								(LPSECURITY_ATTRIBUTES) NULL,           //Security attributes for thread. Default is fine here
    								(DWORD) 0,                              //Initial thread stack size. Again, default is fine
    								(LPTHREAD_START_ROUTINE) &DialogThread, //Pointer to thread function
    								(LPVOID) NULL,                          //Argument for new thread. Not implemented here
    								(DWORD) NULL,                           //Creation flags. None neccesary here
    								(LPDWORD) mainDialogProc_ID);           //Pointer to receive thread ID
    	
    	printf("%d\n",GetLastError());
    	
    	if(!mainDialogProc_Handle)
    	{
    	
    		printf("Error: Could not create DialogThread\n");
    
    	}
    
    
    	return FALSE;
    }
    
    ///////////////////////////////////////////////////////////////////////////////////////////
    Also, here is my code for the function in diologs.h that the thread should be going into (although I'm sure none of this is actually getting executed.)
    Code:
    DWORD WINAPI DialogThread(LPVOID lParam)
    {
    
    	DialogBoxParam(
    		GetModuleHandle(NULL),
    		MAKEINTRESOURCE(IDD_DLG_MAIN), 
    		NULL,
    		(DLGPROC)MainDialogProc,
    		0);
    
    	return FALSE;
    
    }
    This code does absolutely nothing execpt display my two printf functions calls. The weird thing about this mess is that I'm getting a Class does not exist error on my first call to the GetLastError function before my code even makes any calls to the Windows API. After the call to the CreateThread function though, no error occurs, and I actually get a handle to my thread, but it just never excecutes. Can anyone explain why this code won't work, and also why I'm getting that error if the two things aren't related.

  2. #2
    mustang benny bennyandthejets's Avatar
    Join Date
    Jul 2002
    Posts
    1,401
    Try this:
    Code:
    mainDialogProc_Handle = CreateThread(
    								(LPSECURITY_ATTRIBUTES) NULL,           //Security attributes for thread. Default is fine here
    								(DWORD) 0,                              //Initial thread stack size. Again, default is fine
    								(LPTHREAD_START_ROUTINE) DialogThread, //Pointer to thread function *CHANGED*
    								(LPVOID) NULL,                          //Argument for new thread. Not implemented here
    								(DWORD) NULL,                           //Creation flags. None neccesary here
    								(LPDWORD) mainDialogProc_ID);           //Pointer to receive thread ID
    I don't think that's it, but try it anyway.

    Also, place a MessageBox() call in DialogThread() just to notify you if it makes it that far.

    The weird thing about this mess is that I'm getting a Class does not exist error on my first call to the GetLastError function before my code even makes any calls to the Windows API.
    I would assume that this is just a coincidence. Class does not exist may be a default value, or just some garbage that was sitting there when the program executed. Whatever the reason is, it doesn't matter, because you aren't actually really checking for an error at that stage. I would just take the call out of your code.
    [email protected]
    Microsoft Visual Studio .NET 2003 Enterprise Architect
    Windows XP Pro

    Code Tags
    Programming FAQ
    Tutorials

  3. #3
    Registered User Xzyx987X's Avatar
    Join Date
    Sep 2003
    Posts
    107
    Originally posted by bennyandthejets
    Try this:
    Code:
    mainDialogProc_Handle = CreateThread(
    								(LPSECURITY_ATTRIBUTES) NULL,           //Security attributes for thread. Default is fine here
    								(DWORD) 0,                              //Initial thread stack size. Again, default is fine
    								(LPTHREAD_START_ROUTINE) DialogThread, //Pointer to thread function *CHANGED*
    								(LPVOID) NULL,                          //Argument for new thread. Not implemented here
    								(DWORD) NULL,                           //Creation flags. None neccesary here
    								(LPDWORD) mainDialogProc_ID);           //Pointer to receive thread ID
    I don't think that's it, but try it anyway.
    Nope, I already tried that and it didn't help.
    Originally posted by bennyandthejets
    Also, place a MessageBox() call in DialogThread() just to notify you if it makes it that far.
    I already did this with a printf call, that's why I said I was sure the code simply wasn't excecuting.
    Originally posted by bennyandthejets
    I would assume that this is just a coincidence. Class does not exist may be a default value, or just some garbage that was sitting there when the program executed. Whatever the reason is, it doesn't matter, because you aren't actually really checking for an error at that stage. I would just take the call out of your code.
    The default value is 0 for that function and it always started as 0 before I introduced the multithreading code. Oh, and the printf's were just temporary to check for what the problem was, I wasn't planning on leaving them in.

  4. #4
    mustang benny bennyandthejets's Avatar
    Join Date
    Jul 2002
    Posts
    1,401
    Hmmm. I just noticed that you pass a dead pointer to CreateThread(). That may be affecting things, but I'm not sure. You should create an actual DWORD, not a pointer to one:
    Code:
    //Thread IDs
    
    DWORD mainDialogProc_ID;  //Main diolog
    Code:
    mainDialogProc_Handle = CreateThread(
    								(LPSECURITY_ATTRIBUTES) NULL,           //Security attributes for thread. Default is fine here
    								(DWORD) 0,                              //Initial thread stack size. Again, default is fine
    								(LPTHREAD_START_ROUTINE) DialogThread, //Pointer to thread function
    								(LPVOID) NULL,                          //Argument for new thread. Not implemented here
    								(DWORD) NULL,                           //Creation flags. None neccesary here
    								&mainDialogProc_ID);           //Pointer to receive thread ID *CHANGED*
    Give that a shot.
    [email protected]
    Microsoft Visual Studio .NET 2003 Enterprise Architect
    Windows XP Pro

    Code Tags
    Programming FAQ
    Tutorials

  5. #5
    Registered User Xzyx987X's Avatar
    Join Date
    Sep 2003
    Posts
    107
    Nope, no effect.

    EDIT: And trying both suggestions at once didn't work either :\
    Last edited by Xzyx987X; 11-07-2003 at 12:07 AM.

  6. #6
    mustang benny bennyandthejets's Avatar
    Join Date
    Jul 2002
    Posts
    1,401
    Add this right after CreateThread():
    Code:
    WaitForSingleObject(mainDialogProc_ID,INFINITE);
    I suspect the process may be terminating before the thread even starts.
    [email protected]
    Microsoft Visual Studio .NET 2003 Enterprise Architect
    Windows XP Pro

    Code Tags
    Programming FAQ
    Tutorials

  7. #7
    Registered User Xzyx987X's Avatar
    Join Date
    Sep 2003
    Posts
    107
    Hey, it worked. Well, except you tried to pass it the thread ID instead of handle but I fixed that . So does that mean the problem was the CreateThread function doesn't wait till the thread is fully created to continue executing the thread you created it in?

  8. #8
    mustang benny bennyandthejets's Avatar
    Join Date
    Jul 2002
    Posts
    1,401
    Stupid me passed the ID.

    Yes, the problem lies in CreateThread() returning before DialogThread() has had time to run. Normally, you wouldn't terminate the process straight away, because that would defeat the purpose of multithreading. When your program becomes a bit larger, and doesn't quit straight away, you'll be able to remove WaitForSingleObject(). Remember to consider asychronous operation; that is, use mutex objects or some other crazy thing to ensure that only one thread accesses some particular data at a time. Ie, global variables.
    [email protected]
    Microsoft Visual Studio .NET 2003 Enterprise Architect
    Windows XP Pro

    Code Tags
    Programming FAQ
    Tutorials

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. win32 api MDI windows
    By TheNewOne in forum Windows Programming
    Replies: 5
    Last Post: 03-20-2009, 09:11 PM
  2. Use windows API functions in a GTK+ program?
    By Jake.c in forum Windows Programming
    Replies: 19
    Last Post: 01-23-2009, 06:40 AM
  3. Virtual keys
    By Arkanos in forum Windows Programming
    Replies: 4
    Last Post: 12-12-2005, 10:00 AM
  4. Future of Windows API programming ?
    By Dev in forum Windows Programming
    Replies: 7
    Last Post: 04-22-2003, 11:21 PM
  5. Help with editor windows with win api
    By NightStalker in forum Windows Programming
    Replies: 1
    Last Post: 03-13-2003, 03:53 AM