Thread: Multithreading...

  1. #1
    Registered User ~Kyo~'s Avatar
    Join Date
    Jun 2004
    Posts
    320

    Multithreading...

    Ok so let me see if I understand this....

    I can _beginthread(

    pass it a function that can not have parameters with return type of void apparently which will just be the name of the fucntion right?

    Then the second number they say leave 0 it is for stack size allow windows to figure this out on it's own.

    the third param... say I wanted to pass an int why are they casting int to void * wouldn't that do something weird?

    Just trying to figure this out so I can say have the main thread check for incoming connections on a fd. Then let each new fd have it's own thread for inputs / outputs.

    Got code from:
    Multithreading Tutorial - CodeProject

    Code:
    #include <stdio.h>
    #include <windows.h>
    #include <process.h>     // needed for _beginthread()
    
    void  silly( void * );   // function prototype
    
    int main()
    {
        // Our program's first thread starts in the main() function.
    
        printf( "Now in the main() function.\n" );
    
        // Let's now create our second thread and ask it to start
        // in the silly() function.
    
    
        _beginthread( silly, 0, (void*)12 );
    
        // From here on there are two separate threads executing
        // our one program.
    
        // This main thread can call the silly() function if it wants to.
    
        silly( (void*)-5 );
        Sleep( 100 );
    }
    
    void  silly( void *arg )
    {
        printf( "The silly() function was passed %d\n", (INT_PTR)arg ) ;
    }

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    That's pretty much it.

    The reason for void* is that it allows you to pass a pointer to anything.

    You can cast an int to a void* if you want, but the more general approach would be.
    Code:
    int *threadParams = malloc(sizeof *threadParams);
    *threadParams = 42;
    _beginthread( silly, 0, threadParams );
    
    ...
    void  silly( void *arg )
    {
        int *threadParams = arg;
        printf( "The silly() function was passed %d\n", *threadParams ) ;
        free( threadParams );
    }
    It's a bit odd for just a single int, but if you had a struct or an array, it would fit very naturally.

    Using malloc ensures that you always have a block of memory with a clearly defined scope and owner.


    A common mistake is to try this
    Code:
    void foo ( ) {
        int localVar = 42;
        _beginthread( silly, 0, &localVar );
    }
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User ~Kyo~'s Avatar
    Join Date
    Jun 2004
    Posts
    320
    Salem, thanks for the response. I have read a bit and it seems threads can not interact on data correct? So if I had lets say for arguements sake a global variable array with bullets or something thread 1 could not add to the array and then thread 2 add to the same array correct? Or am I misunderstanding what they are saying and they actually mean that thread 1 can not change stuff thread 2 defines in it's operation and vice versa?

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    I was only talking about how you should pass parameters to a new thread.

    There is no problem with threads sharing data, but you do need to be very sure about who as access and when.
    Scroll down your tutorial until you reach "Synchronization Between Threads"

    For example, if two threads are using the same linked list (one adding, one removing), you need to make sure that the two threads are not trying to modify next/prev pointers at the same time. One of them would lose very badly!.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  5. #5
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Don't use _beginthread(). It's conceptually broken. Use _beginthreadex(). Better yet, use a threading library like Boost.Thread.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  6. #6
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by CornedBee View Post
    Don't use _beginthread(). It's conceptually broken. Use _beginthreadex().
    Under windows - which is that platform where some compilers/libraries support those functions - I don't bother with either of those functions. I use the Win32 CreateThread() function instead. _beginthread() and _beginthreadex() are implemented using CreateThread(). So, by using CreateThread() I can do anything that is possible with either _beginthread() and _beginthreadex(), and more.

    Quote Originally Posted by CornedBee View Post
    Better yet, use a threading library like Boost.Thread.
    Generally, I agree with that.

    Win32 is, in practice, a pretty good API, but not the only good one.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  7. #7
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Quote Originally Posted by grumpy View Post
    Under windows - which is that platform where some compilers/libraries support those functions - I don't bother with either of those functions. I use the Win32 CreateThread() function instead. _beginthread() and _beginthreadex() are implemented using CreateThread(). So, by using CreateThread() I can do anything that is possible with either _beginthread() and _beginthreadex(), and more.
    If you link statically with the CRT, using CreateThread() instead of _beginthreadex() means that the CRT will leak thread-specific data blocks.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  8. #8
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by CornedBee View Post
    If you link statically with the CRT, using CreateThread() instead of _beginthreadex() means that the CRT will leak thread-specific data blocks.
    That is only true with code that uses some particular functions for which the CRT (as in Microsoft's LIBCMT.LIB) allocates some static buffers (errno, malloc(), fopen(), strtok(), asctime(), localtime(), and related functions). Additionally, usage of the signal() function can actually fail.

    With all the functions where particular concerns occur, there are alternatives in the Win32 API. The only ones, practically, that cause me any discomfort are malloc() and fopen() but, with a bit of care, it is even possible to avoid those.

    Yes, there is a trade-off (eg more work if wanting to reuse code that employs an affected function in a multithreaded setting). But there are several things that increase difficulty of multithreaded development. Accepting a few restrictions on usage of the CRT is small potatoes in comparison with those.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  9. #9
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    You seriously consider using _beingthreadex() instead of CreateThread() more onerous than completely avoiding malloc() in a C++ program? (Which, by the way, means overriding or avoiding new.)
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  10. #10
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    I didn't suggest that. I said that, with care, it is possible to avoid using malloc(). My point was that statically linking against Microsoft's CRT is avoidable.

    However, since you jumped to such a conclusion with zeal, I don't actually consider avoiding malloc() to be all that onerous. But, then again, I have experience with languages like Fortran 77 (which does not support dynamic memory allocation at all) and also worked in settings where dynamic memory allocation is expressly forbidden - due to regulatory constraints - after program startup, and strongly discouraged during program startup. I therefore consider dynamic memory allocation as useful, but hardly indispensable.

    Incidentally, not all compilers implement operator new in terms of malloc(). And not all compilers that target windows require static linking against Microsoft's CRT.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  11. #11
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    O_o

    If you do happen to link to a library that happens to use one such function you would be in trouble depending on the "MSVCRT" version.

    That said, it is my understanding that this has not been an issue since the MSVC2k5 version came out.

    Soma

  12. #12
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    Only for Vista and up - since they starting using FlsAlloc() for thread local storage - which provides a handy callback for cleanup.

    gg

  13. #13
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    O_o

    That doesn't make any sense considering what you can do with TLS and the "PE" format.

    Still, I'll have take your word for it. I just as soon use `_beginthreadex' on the off chance.

    Soma

  14. #14
    Registered User ~Kyo~'s Avatar
    Join Date
    Jun 2004
    Posts
    320
    I believe _beginthreadex(...) will cover what I am trying to do here. I even think _beginthread(...) would, but since no one objected that _beginthreadex(...) is better than _beginthread(...) I will make the assumption that CornedBee is correct in saying that. Is there a cross platform version if I want to port my code to a *nix system? Seems these all rely on WINAPI reffer to CreateThread Function (Windows)

  15. #15
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by ~Kyo~ View Post
    Is there a cross platform version if I want to port my code to a *nix system?
    There are some open source libraries that implement pthreads (posix threads) under windows. They are sometimes used to port unix programs using posix threading to windows.

    There are also systems, such as Wine, which allow native windows applications to run under other operating systems - including various flavours of unix.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Multithreading Madness?
    By leeor_net in forum Game Programming
    Replies: 4
    Last Post: 09-11-2009, 12:46 AM
  2. Multithreading (flag stopping a thread, ring buffer) volatile
    By ShwangShwing in forum C Programming
    Replies: 3
    Last Post: 05-19-2009, 07:27 AM
  3. multithreading in C++
    By manzoor in forum C++ Programming
    Replies: 19
    Last Post: 11-28-2008, 12:20 PM
  4. Question on Multithreading
    By ronan_40060 in forum C Programming
    Replies: 1
    Last Post: 08-23-2006, 07:58 AM
  5. Multithreading
    By JaWiB in forum Game Programming
    Replies: 7
    Last Post: 08-24-2003, 09:28 PM