Multithreading - synchronisation and keeping track of running threads

This is a discussion on Multithreading - synchronisation and keeping track of running threads within the C Programming forums, part of the General Programming Boards category; As I hope my post title indicates, I'm playing around with multi-threaded design and trying to keep track of threads ...

  1. #1
    Ex scientia vera
    Join Date
    Sep 2007
    Posts
    478

    Multithreading - synchronisation and keeping track of running threads

    As I hope my post title indicates, I'm playing around with multi-threaded design and trying to keep track of threads I've started. I'll describe my application.

    I'm using the FindFirstFile and FindNextFile functions to create a multi-threaded file-searching program, for the kicks. It gets passed a directory path, and it lists the files in the directory and if it finds a directory, it spawns a thread that whose parameters are the path that the directory was found in, and the directory, and the file that's being searched for.

    I'm trying to keep the threads to a maximum of, well, let's say ten. I'm using critical sections to synchronize access to shared resources, such as the paths and directories and so on.

    So, my question is, what is the best way to keep the threads at a maximum of ten? I was thinking I'd use a global integer that'd be incremented every time I spawn a thread, and decremented when a thread returns. Is this bad, or is there a better method to accomplish this?

    Also, is it bad to spawn threads within threads? And is it bad to call WaitForSingleObject within those threads? If it isn't bad, is it a bad design?

    The questions just keep on coming. I just figured out that passing a pointer to a string with the name of the directory to a thread wouldn't be optimal, since the pointer resides in a struct that's on the spawning thread's stack. Is this extremely bad? What would be a better way to do this?

    As you might see, I'm kind of new when it comes to multi-threaded design, and I can see why people say it often results in incessant headbanging against a wall.

    I'd really appreciate any advice on this.

    EDIT: This means that the threads that find a directory spawn more threads and call WaitForSingleObject until it returns - I haven't implemented this, since I have a sneaking suspicion it might result in bad design or at best very inefficient design, so I thought I'd ask first.
    Last edited by IceDane; 10-17-2008 at 09:21 AM.
    "What's up, Doc?"
    "'Up' is a relative concept. It has no intrinsic value."

  2. #2
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,630
    Quote Originally Posted by IceDane View Post
    I'm using the FindFirstFile and FindNextFile functions to create a multi-threaded file-searching program, for the kicks. It gets passed a directory path, and it lists the files in the directory and if it finds a directory, it spawns a thread that whose parameters are the path that the directory was found in, and the directory, and the file that's being searched for.
    This might not be the best idea since Windows will have to search back and forth on the hard drive to fulfill all those threads.
    You should experiment to see if it is indeed more efficient with multiple threads or not.

    So, my question is, what is the best way to keep the threads at a maximum of ten? I was thinking I'd use a global integer that'd be incremented every time I spawn a thread, and decremented when a thread returns. Is this bad, or is there a better method to accomplish this?
    A global variable might do the trick. I certainly don't think it's a bad idea.
    HOWEVER, make sure you use atomic operations or synchronization on that global variable.

    Also, is it bad to spawn threads within threads? And is it bad to call WaitForSingleObject within those threads? If it isn't bad, is it a bad design?
    I wouldn't say it's a bad thing. It depends on the sort of code you're writing and obviously some programs might require this. Besides, a program has at least one thread - the main thread.
    Calling WaitForSingleObject isn't a bad thing - just make sure that it's what you really want, because it will block the thread calling it.

    The questions just keep on coming. I just figured out that passing a pointer to a string with the name of the directory to a thread wouldn't be optimal, since the pointer resides in a struct that's on the spawning thread's stack. Is this extremely bad? What would be a better way to do this?
    Yes, it's very bad.
    Allocate it on the heap with malloc and pass it to the thread. Don't forget that the receiving thread must free it later.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  3. #3
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    A global will work, but you need to use "protection" to prevent race conditions where two threads try to update both threads at once. You could use InterlockedIncrement/InterlockedDecrement to update the counter, but you probably need to use a mutex to prevent someone else from "sneaking in" a thread whilst the current thread is trying to start another thread...

    Using WaitForSingleObject (or it's "multiple" sibling) is fine.

    Using a string from the spawning thread's stack is fine as long as the spawning thread is still alive when the child-thread is finished.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  4. #4
    Ex scientia vera
    Join Date
    Sep 2007
    Posts
    478
    Thanks for the advice.

    I'll be using critical sections to do most of the synchronization, including updating the global variable. And as to whether or not this is more efficient @ Elysia, it's more about understanding multi-threaded design than to create the ultimate file searcher.

    EDIT: Is it possible to get a return value from a thread? I remember seeing some function to do this, but my google searched have proved futile.
    Last edited by IceDane; 10-17-2008 at 09:32 AM.
    "What's up, Doc?"
    "'Up' is a relative concept. It has no intrinsic value."

  5. #5
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  6. #6
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,630
    Quote Originally Posted by IceDane View Post
    ...And as to whether or not this is more efficient @ Elysia, it's more about understanding multi-threaded design than to create the ultimate file searcher.
    Well, just so you know. It's good to know.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Popular pages Recent additions subscribe to a feed

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21