Threads

2»

Comments

  • Heya! I've been all over the place lookin for code that does the job, and is simple. The code at the bottom is the simplest code I've come across, but I need to make a Thread class... I've tried the obvious creating a class around that code, but I get the following error:

    [code]
    error C2664: 'CreateThread' : cannot convert parameter 3 from 'unsigned
    long (void *)' to 'unsigned long (__stdcall *)(void *)'
    None of the functions with this name in scope match the target type
    [/code]

    I asked folks in college, but Windows programming is beyond the scope of the school's courses, so only a small amount of people have a clue. One guy did a little threading before, but could only remember that a cast was needed. But I couldn't find that cast.

    Here's what I've done so far:
    [code]
    #if !defined( THREAD_H )
    #define THREAD_H

    #include
    #include

    #include

    using namespace std ;

    class Thread{
    public:
    DWORD WINAPI ThreadFunc( LPVOID lpParam ) ;
    void run( ) ;

    private:

    };

    #endif THREAD_H

    /**/

    #include
    #include

    #include

    using namespace std ;

    #include "Definitions.h"
    #include "Thread.h"

    DWORD WINAPI Thread::ThreadFunc( LPVOID lpParam ){
    for( int i = 0; i < 10; i++ ){
    cout << "Anting" << endl ;
    }

    cout << "Closed." << endl ;
    return 0;
    }

    void Thread::run( ){
    DWORD dwThreadId[ NUM_THREADS ], dwThrdParam = 1;

    HANDLE hThread[ NUM_THREADS ];

    char szMsg[80];

    for( int i = 0; i < NUM_THREADS; i++ ){
    hThread[ i ] = CreateThread(
    NULL, 0, ThreadFunc, &dwThrdParam, 0, &dwThreadId[ i ]);
    cout << "Thread " << dwThreadId[ i ] << " created." << endl ;
    }

    for( i = 0; i < NUM_THREADS; i++ ){
    // Check the return value for success.
    if (hThread == NULL){
    wsprintf( szMsg, "CreateThread failed." );
    MessageBox( NULL, szMsg, "main", MB_OK );
    }
    else{
    _getch();
    CloseHandle( hThread[ i ] );
    ExitThread( 0 );
    }
    }
    }
    [/code]

    I have another question...
    Before I started turning things into a class, when the program starts it displays the 10 message boxes. If I take out the "CloseHandle( hThread[ i ] );", I'd have to hit any key ten times after hitting 'OK' before the program finished. With the CloseHandle where it is, I need only hit 'OK' ten times (as I would like it). I'm not too familiar with threading, so I'm wondering, is there a better place to stick "CloseHandle"?

    My main question is about fixing the above class. Anyone got any ideas?

    Thanks,
    Tony.



    : [blue]There isn't much to it. If you are using a Windows 32-bit compiler, such as VC++ 6.0 or Dev-C++ just call CreateThread(). Here is a simple example[/blue]
    :
    : [code]
    : #include <windows.h>
    :
    :
    : DWORD WINAPI ThreadProc(LPVOID lpParameter)
    : {
    : // do some stuff not shown
    :
    :
    : return 0;
    : }
    :
    : int main()
    : {
    : DWORD dwThreadID;
    : HANDLE hThread = CreateThread(NULL,0,ThreadProc,0,0,&dwThreadID);
    : return 0;
    : }
    :
    : [/code]
    :
    :

    /*

    Those of you who believe in
    psychokenesis, raise my hand.

    */

  • I think the problem is that you cannot pass a dynamic
    function to CreateThread. I've read somewhere that the only way
    to solve the problem is to declare the thread-func as static.
    That way, the function will be created even if you don't create
    instances of the object owning that function. Some new problems
    usually arise when you do so. The static function will not be
    able to access the object's data. This may be solved by passing in
    a a pointer to the object to the thread-func. (The this-pointer).

    I found some code I made a while a go. Hope it helps you out.

    [code]
    static DWORD WINAPI NamedPipe::watcher( LPVOID lpParam ) {
    #define MSWAIT 0
    NamedPipe *thisObject = (NamedPipe*)lpParam;

    DWORD bytesRead = 0;
    DWORD bytesWritten = 0;
    int result;

    while(1) {
    while(! (thisObject->wantToWriteData || thisObject->wantToReadData)) { //Waiting for user to want to read or write data
    Sleep(MSWAIT);
    }

    if(thisObject->wantToWriteData) { //write
    result = WriteFile(thisObject->pipeHandle, thisObject->buffer, thisObject->bufferSize, &bytesWritten, NULL);
    if(result == 0) { //Error
    thisObject->handleError(GetLastError());
    } else if(result && (int)bytesWritten == thisObject->bufferSize) { //Ikke error. Kan evt. sjekke > 0
    thisObject->wantToWriteData = false;
    thisObject->processingWrite = false;
    thisObject->done = true;
    } else {
    //printf("Error writing data to pipe!
    ");
    }
    Sleep(MSWAIT);

    } else { //read
    result = ReadFile(thisObject->pipeHandle, thisObject->buffer, thisObject->bufferSize, &bytesRead, NULL);
    if(result == 0) { //Error
    thisObject->handleError(GetLastError());

    } else if(result && (int)bytesRead == thisObject->bufferSize) { //Ikke error. Kan evt. sjekke > 0
    thisObject->wantToReadData = false;
    thisObject->processingRead = false;
    thisObject->done = true;
    } else {
    //printf("Error reading data from pipe!
    ");
    }
    Sleep(MSWAIT);

    }

    }


    return 0;

    }

    [/code]

    To start the thread:
    [code]
    watcherThread = CreateThread(NULL, 0, watcher, this, 0, 0);
    [/code]

    : Heya! I've been all over the place lookin for code that does the job, and is simple. The code at the bottom is the simplest code I've come across, but I need to make a Thread class... I've tried the obvious creating a class around that code, but I get the following error:
    :
    : [code]
    : error C2664: 'CreateThread' : cannot convert parameter 3 from 'unsigned
    : long (void *)' to 'unsigned long (__stdcall *)(void *)'
    : None of the functions with this name in scope match the target type
    : [/code]
    :
    : I asked folks in college, but Windows programming is beyond the scope of the school's courses, so only a small amount of people have a clue. One guy did a little threading before, but could only remember that a cast was needed. But I couldn't find that cast.
    :
    : Here's what I've done so far:
    : [code]
    : #if !defined( THREAD_H )
    : #define THREAD_H
    :
    : #include
    : #include
    :
    : #include
    :
    : using namespace std ;
    :
    : class Thread{
    : public:
    : DWORD WINAPI ThreadFunc( LPVOID lpParam ) ;
    : void run( ) ;
    :
    : private:
    :
    : };
    :
    : #endif THREAD_H
    :
    : /**/
    :
    : #include
    : #include
    :
    : #include
    :
    : using namespace std ;
    :
    : #include "Definitions.h"
    : #include "Thread.h"
    :
    : DWORD WINAPI Thread::ThreadFunc( LPVOID lpParam ){
    : for( int i = 0; i < 10; i++ ){
    : cout << "Anting" << endl ;
    : }
    :
    : cout << "Closed." << endl ;
    : return 0;
    : }
    :
    : void Thread::run( ){
    : DWORD dwThreadId[ NUM_THREADS ], dwThrdParam = 1;
    :
    : HANDLE hThread[ NUM_THREADS ];
    :
    : char szMsg[80];
    :
    : for( int i = 0; i < NUM_THREADS; i++ ){
    : hThread[ i ] = CreateThread(
    : NULL, 0, ThreadFunc, &dwThrdParam, 0, &dwThreadId[ i ]);
    : cout << "Thread " << dwThreadId[ i ] << " created." << endl ;
    : }
    :
    : for( i = 0; i < NUM_THREADS; i++ ){
    : // Check the return value for success.
    : if (hThread == NULL){
    : wsprintf( szMsg, "CreateThread failed." );
    : MessageBox( NULL, szMsg, "main", MB_OK );
    : }
    : else{
    : _getch();
    : CloseHandle( hThread[ i ] );
    : ExitThread( 0 );
    : }
    : }
    : }
    : [/code]
    :
    : I have another question...
    : Before I started turning things into a class, when the program starts it displays the 10 message boxes. If I take out the "CloseHandle( hThread[ i ] );", I'd have to hit any key ten times after hitting 'OK' before the program finished. With the CloseHandle where it is, I need only hit 'OK' ten times (as I would like it). I'm not too familiar with threading, so I'm wondering, is there a better place to stick "CloseHandle"?
    :
    : My main question is about fixing the above class. Anyone got any ideas?
    :
    : Thanks,
    : Tony.
    :
    :
    :
    : : [blue]There isn't much to it. If you are using a Windows 32-bit compiler, such as VC++ 6.0 or Dev-C++ just call CreateThread(). Here is a simple example[/blue]
    : :
    : : [code]
    : : #include <windows.h>
    : :
    : :
    : : DWORD WINAPI ThreadProc(LPVOID lpParameter)
    : : {
    : : // do some stuff not shown
    : :
    : :
    : : return 0;
    : : }
    : :
    : : int main()
    : : {
    : : DWORD dwThreadID;
    : : HANDLE hThread = CreateThread(NULL,0,ThreadProc,0,0,&dwThreadID);
    : : return 0;
    : : }
    : :
    : : [/code]
    : :
    : :
    :
    : /*
    :
    : Those of you who believe in
    : psychokenesis, raise my hand.
    :
    : */
    :
    :

  • Thanks! :) That solves also solves problem I didn't ask about! :)

    Thanks lots! :)

    Tony.
    /*

    Those of you who believe in
    psychokenesis, raise my hand.

    */

  • what are all those directives and API stuff? Geeze, does nobody use SIMPLE datatypes and stuff anymore? I don't know what that means, createThread(NULL,blab,blah...). besides, how does that say what the thread is going to do? datatypes are int, char, double, and float. You can call them long, short, unsigned, *, **, *****.... but I don't know what the hell a *void_dcll(*void)*Q_rightArm_void* is! and what is a namespace?

    Is there a SIMPLE way to just say "Thread blah = new Thread(..); Thread.run(this_code_over_here);"? How ever it's done, can you just tell me the syntax?

    Bye the way, is this something that is ONLY available through win API or something, cause I am sick of seeing all this weird code and syntax out there as is EVERYBODY knows all about it and all the weird MADE UP datatypes and stuff...I thought C++ was C++, and not something that you could use to make your own programming language out of using stuff that would NORMALLY give ten billion errors and flat out not make sense...well, whatever; just how do you declare/start a thread, and how do you stop them? SIMPLY [or is that possible]?
  • [blue]When in Rome, do as the Romans do. When writing a Windows program you have to use Windows API functions and data types (thanks to Bill $$$ for that one!). I know it's difficult when you first start learning Windows programming, but it'll come to you eventually. There's about a year's learning curve (or more).


    There are actually several ways to create a thread. Using the new operator will not help. CreateThread() really isn't all that hard once you learn that most of the parameters are 0 (or NULL) and that the thread function must be either a static method or a simple C-style function. [/blue]


    : what are all those directives and API stuff? Geeze, does nobody use SIMPLE datatypes and stuff anymore? I don't know what that means, createThread(NULL,blab,blah...). besides, how does that say what the thread is going to do? datatypes are int, char, double, and float. You can call them long, short, unsigned, *, **, *****.... but I don't know what the hell a *void_dcll(*void)*Q_rightArm_void* is! and what is a namespace?
    :
    : Is there a SIMPLE way to just say "Thread blah = new Thread(..); Thread.run(this_code_over_here);"? How ever it's done, can you just tell me the syntax?
    :
    : Bye the way, is this something that is ONLY available through win API or something, cause I am sick of seeing all this weird code and syntax out there as is EVERYBODY knows all about it and all the weird MADE UP datatypes and stuff...I thought C++ was C++, and not something that you could use to make your own programming language out of using stuff that would NORMALLY give ten billion errors and flat out not make sense...well, whatever; just how do you declare/start a thread, and how do you stop them? SIMPLY [or is that possible]?
    :

  • Also, if you're new to Win32 API function (and I suspect from your comments that you are), here is a tutorial to get you started.

    http://www.winprog.org/tutorial/

Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories