Thread: How to make the program not to wait for the function?

  1. #1
    Reverse Engineer maxorator's Avatar
    Join Date
    Aug 2005
    Location
    Estonia
    Posts
    2,318

    How to make the program not to wait for the function?

    How to make the program not to wait for the function? Well, I have a downloading program (uses URLDownloadToFile), but while it's downloading, the program is not responding (because it waits for the function). How can I make the program not wait for the function?

  2. #2
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    You'd probably want to use the advanced notion of threads.

  3. #3
    Reverse Engineer maxorator's Avatar
    Join Date
    Aug 2005
    Location
    Estonia
    Posts
    2,318
    Advanced notion of threads???

  4. #4
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    C++ (like C) does not inherently support the notion of allowing a function to execute in parallel with something else.

    The way it is done, in practice, is to use multithreading techniques. That is typically done using library functions that, although not described in the C or C++ standards, are available on quite a few modern operating systems (eg windows, unix variants). The problem is, the libraries used (and the names of functions in them) are generally operating system dependent.

    Under most modern variants of unix, the POSIX standard is supported. POSIX covers a number of things, including creation of threads and synchronisation mechanisms (I'll come back to that below). Essentially that means there is a way to use multithreading which is largely portable between unix variants. The problem with POSIX is that some things are very loosely specified, so there is some variation of what behaviour is achieved. Windows is also POSIX compliant, but the loose bits in the POSIX specification are interpreted differently by Microsoft --- hence a portability issue of taking a posix compliant program from unix to windows or vice versa. Windows also supports the win32 API, and some of the functions in that API are also related to multithreading and synchronisation mechanisms.

    Multithreaded programming is usually described as an "advanced" topic. Not because of the portability issues above, but because of issues of interactions between threads. If two threads are accessing the same data concurrently, all sorts of trouble can break loose (particularly if one thread modifies data while another is reading it). There is no inherent mechanism in any operating system that ensures such issues do not occur. Instead, it is necessary to design the program to ensure that they do not. The usual method to do that is using objects designed for use with synchronisation (particular types of these objects are called mutexes, critical sections, or semaphores): essentially a lock that one thread locks before accessing shared data, and the other threads are required to wait for the lock to be released before accessing the same data. Such things are done explicitly by the program: in most cases, neither the operating system nor a compiler can FORCE a program to do synchronisation before accessing shared data. The result is that use of multithreading suddenly requires explicit consideration of how to synchronise access to data that is accessed from multiple threads (particularly if one of more threads modifies the shared data).

    Things get even more complicated if multiple locks are employed (eg lock A is used to synchronise access to data X, and lock B is used to synchronise access to data Y). The reason this gets more complicated is that some threads may need access to data X and data Y. This means it is necessary to acquire both locks A and B. Picture a scenario where thread 1 acquires lock A first, and then lock B, but thread 2 acquires lock B first and then lock A. The problem with this is that thread 1 may succeed in acquiring lock A. But, then thread 2 comes along and acquires lock B. Then thread 1 attempts to acquire lock B, and is forced to wait for thread 2 to release it. But thread 2 then attempts to acquire lock A, which means it is forced to wait on thread 1. The result is deadlock: both thread 1 and thread 2 are waiting on the other to release a lock held by the other.

    There are piles of issues with using threads, and synchronisation between them. The example I've given with a deadlock is a simple one. There are lots of other ways in which multithreaded programs can get in trouble. The next effect is that designing a multithreaded program is far from trivial. And, importantly, if you are doing things in multiple threads, the usual reason is that --- at some point --- the results of actions in multiple threads will come together in one place (eg to be displayed in a GUI). That "bringing together in one place" implies a need for synchronisation.

  5. #5
    Deprecated Dae's Avatar
    Join Date
    Oct 2004
    Location
    Canada
    Posts
    1,034
    So... isnt there an alternative to multithreading to have a program respond while its operating on something?
    Warning: Have doubt in anything I post.

    GCC 4.5, Boost 1.40, Code::Blocks 8.02, Ubuntu 9.10 010001000110000101100101

  6. #6
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Asynchronous calls, but that only works with some special functions that were made for it, like ReadFile.
    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

  7. #7
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by Dae
    So... isnt there an alternative to multithreading to have a program respond while its operating on something?
    Well, yeah, but then you have the problem of getting the program to respond to something while it's operating on something else.

    You can do it with asynchoronous operations (eg ReadFileEx() under windows), but that also relies on very specialised support by the underlying operating system. And is inherently non-portable as well: the functions used for asynchoronous reading, and triggering a response in the affected program when the read operation is completed, are even more specialised --- and therefore non-portable --- than threading functions.

    Similarly, it can be done with interrupts at the hardware level (depending on your hardware) but, on most operating systems, you can't respond to interrupts directly.

    There is also a technique known as "coroutines", which essentially requires you to break up your code into lots of small functions, and an executive executes those small pieces in sequence and checks for other events between the pieces. Designing coroutines is probably even more challenging than designing a program for multi-threading, as you also need to manage the scheduling of the coroutines.

  8. #8
    It's full of stars adrianxw's Avatar
    Join Date
    Aug 2001
    Posts
    4,829
    My very basic MT tutorial with Windows starts here.
    Wave upon wave of demented avengers march cheerfully out of obscurity unto the dream.

  9. #9
    Registered User
    Join Date
    Nov 2002
    Posts
    491
    libcurl has asynch api you can use to avoid threading. Writing a threaded program without understanding the ins-and-outs of concurrency in a non-concurrent orientated language is probably going to lead to a disaster. I'd try to get a strong grasp on concurrency first if you want to use it to sovle yoru problem.

  10. #10
    Deprecated Dae's Avatar
    Join Date
    Oct 2004
    Location
    Canada
    Posts
    1,034
    Thanks for the info, so do most programs use multithreading? Well.. I guess most do pause when they are saving files and such, but you've got things like P2P clients (or M$ WMP) that are searching, downloading, playing music/video, displaying a clock, and more all at the same time and dont pause (often).
    Warning: Have doubt in anything I post.

    GCC 4.5, Boost 1.40, Code::Blocks 8.02, Ubuntu 9.10 010001000110000101100101

  11. #11
    Registered User
    Join Date
    Nov 2002
    Posts
    491
    It depends on who wrote them. With Asynch API's you can write it all in 1 thread. See http://www.twistedmatrix.com/ for an example.
    http://threading.2038bug.com/index.html has some good information, don't take it's title too seriously.
    http://www.kegel.com/c10k.html For an example of how threading doesn't really scale in non-Concurrent Orientated Langauges.
    http://mozart-oz.org/ and http://www.erlang.org/ for examples of concurrent orientated langauges (where you concurrency is so lightweight you can have thousands of paths of execution).

    The actions you listed can generally be handled in a single thread simply by passing events around.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Undefined Reference Compiling Error
    By AlakaAlaki in forum C++ Programming
    Replies: 1
    Last Post: 06-27-2008, 11:45 AM
  2. make the printer function on my program!!!!
    By SweeLeen in forum C++ Programming
    Replies: 3
    Last Post: 03-18-2006, 11:48 AM
  3. Bisection Method function value at root incorrect
    By mr_glass in forum C Programming
    Replies: 3
    Last Post: 11-10-2005, 09:10 AM
  4. Change this program so it uses function??
    By stormfront in forum C Programming
    Replies: 8
    Last Post: 11-01-2005, 08:55 AM
  5. Replies: 5
    Last Post: 02-08-2003, 07:42 PM