Thread: multi-threaded programming

  1. #16
    Never Exist Hermitsky's Avatar
    Join Date
    Jul 2004
    Posts
    149
    oh sorry, i see it ......

    blow me ... ...

  2. #17
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    Yes, exactly that. The C and C++ libraries need some additional housekeeping when starting and ending threads, so you need to use _beginthread[ex] and _endthread[ex], which perform this housekeeping.
    If this is the case, then why would anybody ever use CreateThread()? If no components of the STL can be used in a thread created with CreateThread(), doesn't that render it rather useless except for situations in which the thread performs extremely simple tasks? And if it's useless, then why did MS bother including it in the Windows API?
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  3. #18
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    >> And if it's useless, then why did MS bother including it in the Windows API? <<

    What do you think _beginthreadex() calls? _beginthreadex() is part of the C run-time library, CreateThread is the operating system function. Many applications don't even use C/C++, let alone the C run-time library.

    >> If this is the case, then why would anybody ever use CreateThread()? <<

    Often, you are only creating a few worker threads. In this case the small (4KB per thread according to some reports) memory leak is insignificant. Other applications do not destory their threads at all.

    According to this informative post on the issue, only certain functions will trigger the memory leak.
    _beginthread vs CreateThread

    To wrap this up, if CreateThread/ExitThread (or a simple return)
    is used in an app which uses parts of the C MT-RTL that needs
    per-thread data, memory leaks will occur.

    Some of the goodies inside the MT C-RTL's per-thread data struct are:

    errno
    doserrno
    Floating Point data segment
    rand() seed value
    ptr to strtok() token
    ptr to wcstok() token
    ptr to _mbstok() token
    ptr to strerror()/_strerror() buff
    ptr to tmpnam() buffer
    ptr to _wtmpnam() buffer
    ptr to tmpfile() buffer
    ptr to _wtmpfile() buffer
    ptr to asctime() buffer
    ptr to _wasctime() buffer
    ptr to gmtime() structure
    ptr to ecvt()/fcvt buffer
    stuff for signal handling and fp exceptions
    per-thread data needed by C++ Exception Handling

    So, if you never use anything of the above, you would probably be
    sure that you're not leaking memory. Or, if using these things,
    you should call _endthreadex() instead of ExitThread().

    BTW, you should always use _beginthreadex() instead of _beginthread()
    since _beginthread() is old, unreliable (it has a thread handle
    race condition) and lacks important parameters you'll need for
    any serious MT app development.
    And this what MSDN says on the matter.
    Quote Originally Posted by MSDN CreateThread
    A thread in an executable that is linked to the static C run-time library (CRT) should use _beginthread and _endthread for thread management rather than CreateThread and ExitThread. Failure to do so results in small memory leaks when the thread calls ExitThread. Another work around is to link the executable to the CRT in a DLL instead of the static CRT. Note that this memory leak only occurs from a DLL if the DLL is linked to the static CRT and a thread calls the DisableThreadLibraryCalls function. Otherwise, it is safe to call CreateThread and ExitThread from a thread in a DLL that links to the static CRT
    In summary, if you are creating a half-dozen worker threads or even a couple of hundred that won't be destroyed, then don't worry about using CreateThread(). On the other hand, if you are creating a temporary thread to handle every request in a web server, you better think about it.
    Last edited by anonytmouse; 11-27-2004 at 10:35 PM.

  4. #19
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    Great link, thanks

    >>Often, you are only creating a few worker threads. In this case the small (4KB per thread according to some reports) memory leak is insignificant, if the threads are destroyed at all.

    Since _beginthreadex() has all the same functionality as CreateThread() and doesn't have the potential memory leak, doesn't that mean there is really no reason at all to use CreateThread()? Or is it a speed/performance thing...
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  5. #20
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    >> Compiler/IDE: MSVC++ 6.0 Pro Edition
    Then you have the MS-CRT source code, including beginthreadex()
    Take a look-see, it's nothing fancy.

    gg

  6. #21
    Toaster Zach L.'s Avatar
    Join Date
    Aug 2001
    Posts
    2,686
    As a side note, STLport claims that their implementation of the C++ Standard Library is thread safe. Has anyone tested and confirmed/refuted this?
    The word rap as it applies to music is the result of a peculiar phonological rule which has stripped the word of its initial voiceless velar stop.

  7. #22
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Testing for thread safety is extremely hard. Mostly you can only design and hope.

    I see absolutely no reason to call CreateThread when you can call _beginthreadex. I wonder, though, will there be a leak if I call CreateThread and ExitThread or only if I call _beginthreadex and then ExitThread?
    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. #23
    Toaster Zach L.'s Avatar
    Join Date
    Aug 2001
    Posts
    2,686
    Certainly hard, but at least to some extent it can be done (i.e. you can prove it isn't thread safe, but not so easily the other way around).

    Perhaps this is a better wording of the question: Has anybody had experience writing multi-threaded code with STLport, and if so, how well did it behave?
    The word rap as it applies to music is the result of a peculiar phonological rule which has stripped the word of its initial voiceless velar stop.

  9. #24
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    I have, and yes it's thread safe (I've yet to expose a bug atleast) - but not "thread safe" in the way that some readers are probably thinking.

    http://www.stlport.org/doc/sgi_stl.html#thread_safety

    • simultaneous read access to the same container from within separate threads is safe;
    • simultaneous access to distinct containers (not shared between threads) is safe;
    • user must provide synchronization for all accesses if any thread may modify shared container.
    gg
    Last edited by Codeplug; 11-28-2004 at 12:32 PM.

  10. #25
    Toaster Zach L.'s Avatar
    Join Date
    Aug 2001
    Posts
    2,686
    Thanks.
    Yeah, that's what I expected for "thread-safety". Good to know it works as advertised.

    Cheers
    The word rap as it applies to music is the result of a peculiar phonological rule which has stripped the word of its initial voiceless velar stop.

  11. #26
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    >>Then you have the MS-CRT source code, including beginthreadex()
    Uh.. what exactly is the MS-CRT? MS component runtime? Cathode ray tube? Cryptographical relay team? Cowardly rebellious tuna?

    will there be a leak if I call CreateThread and ExitThread or only if I call _beginthreadex and then ExitThread?
    Apparently so
    But how can this memory get allocated if _beginthreadex() isn't used
    in the first place?

    Well, for starters, any RTL function that needs to access "global"
    data (e.g., errno) contained in the per-thread data struct, will first
    check if the struct is allocated; and if not, allocate memory for it, itself.
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  12. #27
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    CRT stands for C RunTime as defined by the ISO C standard, and MS-CRT is Microsoft's implementation of the same.
    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

  13. #28
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    Ok, thanks. I'll take a look at it.
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  14. #29
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    >> I see absolutely no reason to call CreateThread when you can call _beginthreadex.
    If you don't use or link to the CRT, that's a good reason to use CreateThread

    >> I wonder, though, will there be a leak if I call CreateThread and ExitThread or only if I call _beginthreadex and then ExitThread?
    The memory which is potentially leaked, comes from a per-thread structure that is allocated off the heap. In order to understand when the leak occurs, we need to know (a) when the structure is allocated, and (b) when the structure is free'd.

    When is it allocated?
    • When _beginthread[ex] is called.
    • When any CRT function is called that creates the global structure (so it can use it).

    When is it free'd?
    • When _endthread[ex] is called.
    • When _beginthread[ex] is used, _endthread[ex] is called for you auto-magically.
    • When linked to the CRT dynamically, [edit] the structure is free'd. [/edit]

    When is memory leaked?
    • When linking statically with the CRT -> and CreateThread() is used -> and the thread calls a CRT function that allocates the global structure -> and the thread does not call _endthread[ex].
    • When a DLL module calls DisableThreadLibraryCalls() -> then satisfies the first bullet.

    gg
    Last edited by Codeplug; 11-28-2004 at 01:53 PM.

  15. #30
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    If you don't use or link to the CRT, that's a good reason to use CreateThread
    I consider that a situation in which you can't call _beginthreadex
    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

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Help printing a multi array
    By cjohnman in forum C Programming
    Replies: 4
    Last Post: 05-05-2008, 01:35 PM
  2. multi threaded program
    By Dash_Riprock in forum C++ Programming
    Replies: 6
    Last Post: 08-27-2006, 08:38 AM
  3. starting to learn multi threading
    By hanhao in forum C++ Programming
    Replies: 2
    Last Post: 06-09-2004, 01:44 PM
  4. Replies: 6
    Last Post: 04-26-2004, 10:02 PM
  5. Signals in multi threaded application
    By HelpMe in forum C Programming
    Replies: 0
    Last Post: 09-12-2001, 09:15 PM