1

I've read various articles and similar questions, and I know that the two concepts are different, but I don't seem to know the correct answer.

I understood that thread is in terms of number of workers, and sync/async is in terms of task order. I would like to ask if my understanding is correct, with the following example.

Have to make a sandwich.

  1. Bake bread.
  2. Fry the eggs.
  3. Combine.

A thread == a frying pan.

  • Single-thread & sync:
    1. Put the bread on the frying pan.
    2. just watch until the bread is all baked.
    3. When the bread is baked, remove the bread from the pan and put the eggs on that pan.
  • Multi-thread & async:
    1. Multiple pans.
    2. Put the bread and eggs on different pans, respectively.
    3. No matter what you put first, take out the completed one.
  • Single-thread & async:
    1. One pan.
    2. Put the bread on the pan.
    3. The bread was not all baked, but put it aside for a while and put the eggs on that pan.
    4. The eggs aren't all fried, but I'll just put them away and put the bread on the pan.
    5. Repeat...
  • Multi-thread & sync:
    1. There are several pans, but we will bake the bread on pan1 first.
    2. When the bread on pan1 is finished, fry the eggs on pan2.

Is my understanding correct?

+) If so, case single-thread / async like javascript, the task in the event loop is just waiting in the queue and not progressing, right?

0

1 Answer 1

1

The example is great & funny. Do not forget to take later the other one for "Multi-thread & async" otherwise it will be burnt ;) . Otherwise, It seems correct overall to me.

The example is not very good for the "Single-thread & async" case though and it might be the source of confusion. In practice, the pre-emption (switch between the eggs and the bread) is not guaranteed in async. It is generally done cooperatively. The problem is that in you example the bread cannot be cooked while the eggs are since there is only 1 pan. In practice, a task like I/Os operations can progress without using any core (ie. pan).

Async is mainly useful to avoid waiting a task completion while something else can be done. It is not really useful for computing tasks. For example, if you cook 2 sandwiches for 2 friends and you do not know if they like eggs or beacon, you need to ask them. This task can be async: you can ask the first, then the second, then cook the bread using 1 or 2 pan, then check the answers before cooking the eggs/beacon. Without async, you have to wait for the answer (possibly in a thread) before cooking the bread (which is not efficient).

Async operation can be split in multiple parts:

  1. starting the request (eg. send a message to a friend)
  2. checking the state or triggering events (eg. checking your friend messages or react to them when received)
  3. completing the request (eg. start cocking what your friends want) which can include starting new requests (done in 1.)

The part 2 is dependent of the language/framework. Moreover, regarding the language/framework, there is sometime a part consisting in waiting for the task to be completed (blocking operation). It can be done by looping on the part 2 until the state is completed, but sometime it can be done a bit more efficiently.

Sign up to request clarification or add additional context in comments.

7 Comments

Thank you for answer. But there seems to be something I don't understand. 1.the switch between bread and egg is not async, does that mean that the order is not guaranteed like b - e - b - e ? 2. Can I understand the problem in your example to mean that my example doesn't make assumptions about non-CPU(pan) tasks?
off topic) My understanding of I/O operations may be lacking. Isn't the process taking up CPU in Blocking I/O operation? Even if it is non-blocking, does not use the CPU in kernel mode for a while?
1. Yes the order is not guaranteed. This is very dependent of the target framework / async method though. But generally, an async task will continue until it has to wait for some work, or until the work is completed. In that case, the task itself cooperatively temporary stop itself and let other ones run. This is very different from multithreading where the OS regularly switch between two threads when they compete for the same cores (pre-emption). A slow async process that is not very cooperative can prevent others to be executed for a long time. A possible execution is b - b - e - e.
2. I am not sure to understand your point. I would say that your example does not consider tasks other than CPU-intensive ones (ie. pan-greedy). Is it more clear?
I/O operations are a bit complex and things changed over time. The method to deal with async I/O operations is dependant of the application, the OS, and the actual APIs. Blocking I/Os is quite the standard since the last decade but it is not the best solution. When an application use blocking operations for example to read a file, it make a request to the OS which add it to a queue that can be computed by another thread later or directly. Unless the OS can directly provide the result, the requesting thread is interrupted by the OS and it is put in a waiting list.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.