2

In a uniprocessor (UP) system, there's only one CPU core, so only one thread of execution can be happening at once. This thread of execution is synchronous (it gets a list of instructions in a queue and run them one by one). When we write code, it compiles to set of CPU instructions.

How can we have asynchronous behavior in software on a UP machine? Isn't everything just run in some fixed order chosen by the OS?

Even an out-of-order execution CPU gives the illusion of running instructions in program order. (This is separate from memory reordering observed by other cores or devices in the system. In a UP system, runtime memory reordering is only relevant for device drivers.)

Arashsoft
  • 2,749
  • 5
  • 35
  • 58
  • threads, other processes, blah blah blah. just because a simple program executes serially doesn't mean ALL programs do so as well. – Marc B Jul 19 '16 at 18:35
  • 1
    The OS can [interrupt the CPU](https://en.wikipedia.org/wiki/Interrupt) (it saves the CPU state, including 'instruction address', etc) and changes *which* bit of 'synchronous' bit of code executing. This gives the overall effect of concurrent execution by alternating through very many small 'synchronous' parts of a program. This is leveraged by the OS to provide concurrent threads and/or processes (including those required for IO processing) which are in turn leveraged by runtimes to provide asynchronous behavior. (And, of course, some processors are really packages of *independent* CPUs.) – user2864740 Jul 19 '16 at 18:37
  • @user2864740 OS is running on the CPU too. Assume that we have a single thread cpu, then it is not possible to have real async code. – Arashsoft Jul 19 '16 at 18:39
  • @Arashsoft "This gives the overall effect of concurrent execution *by alternating through very many small 'synchronous' parts of a program*." This effect is amplified (or even not strictly needed to answer the question) on true multi-core / multi-threaded (eg. hyper-v) processors. – user2864740 Jul 19 '16 at 18:40
  • The total ordering of operations between two threads is not well defined. Even sequential consistency just guarantees that there *is* an order, not what the order is. See for example https://www.think-cell.com/en/career/talks/pdf/think-cell_talk_memorymodel.pdf. Also http://preshing.com/20120930/weak-vs-strong-memory-models/ – Peter Cordes Jul 19 '16 at 18:43
  • 1
    @user2864740, I think I got my answer based on your comments. "very many small 'synchronous' parts" that we run one after another is what we call asynchronous. So the answer is real asynchronous is not possible. – Arashsoft Jul 19 '16 at 19:32

2 Answers2

5

An interrupt handler is a piece of code that runs asynchronously to the rest of the code, and can happen in response to an interrupt from a device outside the CPU. In user-space, a signal handler has equivalent semantics.

(Or a hardware interrupt can cause a context switch to another software thread. This is asynchronous as far as the software thread is concerned.)

Events like interrupts from network packets arriving or disk I/O completing happen asynchronously with respect to whatever the CPU was doing before the interrupt.

Asynchronous doesn't mean simultaneous, just that it can run between any two machine instructions of the rest of the code. A signal handler in a user-space program can run between any two machine instructions, so the code in the main program must work in a way that doesn't break if this happens.

e.g. A program with a signal-handler can't make any assumptions about data on the stack below the current stack pointer (i.e. in the un-reserved part of the stack). The in the x86-64 SysV ABI is a modification to this rule for user-space only, since the kernel can respect it when transferring control to a signal handler. The kernel itself can't use a red-zone, because hardware interrupts write to the stack outside of software control, before running the interrupt handler.


In an OS where I/O completion can result in the delivery of a POSIX signal (i.e. with POSIX async I/O), the timing of a signal can easily be determined by the timing of a hardware interrupts, so user-space code runs asynchronously with timing determined by things external to the computer. It's not just an issue for the kernel.


On a multicore system, there are obviously far more ways for things to happen in different orders more of the time.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
  • Your answer is about interrupts come from hardware to cpu such as I/O interrupts. I do not have any issue with them because other hardware are doing their job asynchronous to cpu. My question is about two peace of code that we want to run them in cpu. – Arashsoft Jul 19 '16 at 19:29
  • 1
    @Arashsoft: An interrupt handler is a piece of code that runs asynchronously to the rest of the code. In user-space, a signal handler has equivalent semantics. Asynchronous doesn't mean simultaneous, just that it can run between any two machine instructions of the rest of the code. – Peter Cordes Jul 20 '16 at 01:42
1

Many processors are capable of multithreading, and many operating systems can simulate multithreading on single-threaded processors by swapping tasks in and out of the processor.

Robert Columbia
  • 6,313
  • 15
  • 32
  • 40
  • Considering that OS is running on the same CPU, even if it simulate multi threading by giving and getting cpu from different tasks, it is not a real async running (tasks does not run at the same time). – Arashsoft Jul 19 '16 at 18:41
  • Perhaps, but it is async "enough" for most purposes. If you want true asynchronous processing, you could set up a Beowulf cluster or something like that. – Robert Columbia Jul 19 '16 at 18:47
  • 1
    @Arashsoft asynchrony does not require that tasks run at the very same time. – Alexei Kaigorodov Jul 19 '16 at 18:55