I'm new to this concept. Are these the same or different things? What is the difference? I really like the idea of being able to run two processes at once, for example if I have several large files to load into my program I'd love to load as many of them simultaneously as possible instead of waiting for one at a time. And when working with a large file, such as wav file, it would be great to break it into pieces and do processing on several chunks at once and then put them back together. What do I want to look into to learn how to do this sort of thing?
Edit: Also, I know using more than one core on a multicore processor fits in here somewhere, but apparently asynchronous programming doesn't necessarily mean you are using multiple cores? Why would you do this if you didn't have multiple cores to take advantage of?
I think in general, all these are design related rather than language related. Same apply to multicore programming.
To reflect Jim, it's not only the file load scenario. Generally, you need to design the whole software to run concurrently in order to feel the real benefit of multi-threading, task based or asynchronous programming.
Try see things from a grand picture point of view. Understand the over all modelling of a specific example and see how these methodologies are implemented. It'll easy to see the difference and help understand when and where to use which.
They are related but different.
Threading usual refers to the simplest form of multi-threading, which is when you have a small set of threads each doing a specific task that needs to be, or could benefit from running simultaneously. For example, this could be a
GUI
application where you might have one thread handling the drawing of elements, another thread responding to events like mouse clicks, and another thread doing some background processing. But threading could also refer more generally to any kind of multi-threading (i.e., a "thread" is a fundamental construct for all multi-threading, it is a thread of execution). When that idea of having a set of threads each doing their own thing is taken to an extreme, we usually start to talk about an Agent-based approach.Task-based approach refers to a specific strategy in software engineering where, in abstract terms, you dynamically create "tasks" to be accomplished, and these tasks are picked up by a task manager that assigns the tasks to threads that can accomplish them. This is more of a software architectural thing. The advantage here is that the execution of the whole program is a succession of tasks being relayed (task A finished -> trigger task B, when both task B and task C are done -> trigger task D, etc..), instead of having to write a big function or program that executes each task one after the other. This gives flexibility when it is unclear which tasks will take more time than others, and when tasks are only loosely coupled. This is usually implemented with a thread-pool (threads that are waiting to be assigned a task) and some message-passing interface (MPI) to communicate data and task "contracts".
Asynchronous programming does not refer directly to a kind of multi-threading program program, although they are very often associated (and work well together). A synchronous program might go a little bit like this: "do this task", "wait until done", "do something with results", and "move on to something else". An asynchronous program might go a little more like this: "I'm gonna need the result of this task to do something with the result", and "for now, I'll move on to something else, and expect the result later (and wait if I have to)". But notice that "asynchronous" is a very broad concept, but it always involves a form of "just tell me when it's done" instead of the traditional "do it now!". This does not require multi-threading, in which case it just becomes a software design choice (which often involves callback functions and things like that to provide "notification" of the asynchronous result). But, obviously, with multiple threads, it becomes more powerful, as you can do something else while you expect the result of some asynchronous task. Taken to the extreme, it can become a more full-blown architecture like a task-based approach (which is one kind of asynchronous programming technique).
I think that the thing that you are describing that you need correspond more to yet another concept: Parallel Computing (or parallel processing). This approach is more about splitting a large processing task into smaller parts and processing all parts in parallel, and then combining the results. You should look into libraries like OpenMP or
OpenCL / CUDA
(for GPGPU).Yeah, as I said, asynchronous programming does not necessarily involve anything happening concurrently (multiple threads), but then it boils down to being a software design choice, and often a good one, I might add. And then, there are also other contexts in which the word "asynchronous" is used, such as asynchronous I/O, which is a completely different concept that has nothing to do with multi-threading.
If you don't have multiple cores, the advantages of multi-threading have little to do with performance directly (in the sense of crunching more numbers per second), but rather with flexibility in the design and being able to reuse "waiting time" (e.g., don't "block" the processing because you need some time to wait on file I/O or network I/O). Also, in case of "threading" (as defined above), the motivation is just to have different tasks running simultaneously (or seem to). But you are correct in that before multi-core
CPU
s, there wasn't as much of an incentive to do multi-threading, as the gains often do not justify the overhead.