zoukankan      html  css  js  c++  java
  • Operating System: Three Easy Pieces --- Concurrency: An Introduction (Note)

    Thus far, we have seen the development of the basic abstractions that the OS performs. We have

    seen how to take a single physical CPU and turn it into multiple virtual CPUs, thus enabling the

    illusion of multiple programs running at the same time. We have also seen how to create the

    illusion of a large, private virtual memory for each process; this abstraction of the address space

    enables each program to behave as if it has its own memory when indeed the OS is secretly

    multiplexing address spaces across physical memory (and sometimes, disk).

    In this note, we introduce a new abstraction for a single running process: that of a thread. 

    Instead of our classic view of a single point of execution within a program (i.e., a single PC

    where instructions are being fetched from and executed), a multi-threaded program has more

    than one point of execution (i.e., multiple PCs, each of which is being fetched and executed

    from). Perhaps another way to think of this is that each thread is very much like a separate

    process, except for one difference: they share the same address space and thus can access

    the same data.

    The state of a single thread is thus very similar to that of a process. If has a program counter

    (PC) that tracks where the private set of registers it uses for computation; thus, if there are two

    threads of that are running on a single processor, when switching from running one (T1) to

    running the other (T2), a context switch must take place. The context swtich between threads 

    is quite similar to the context switch between processes, as the register state of T1 must be

    saved and the register state of T2 restored before running T2. With processes, we saved state

    to a process control block; now, we will need one or more thread control blocks to store the 

    state of each thread of a process. There is one major difference, though, in the context switch

    we perform between threads as compared to processes: the address space remains the same

    (i.e., there is no need to switch which page table we are using).

    One other major difference between threads and processes concerns the stack. In our simple

    model of the address space of a classic process (which we can now call a single-threaded

    process), there is a single stack, usually residing at the bottom of the address space.

    However, in a multi-threaded process, each thread runs independently and of course may

    call into various routines to do whatever work it is doing. Instead of a single stack in a

    space, there will be one per thread. Let's say we have a multithreaded process that has

    two threads in it; the resulting address space looks different.

    In this figure, you can see two stacks spread throughout the address space of the process.

    Thus, any stack-allocated variables, parameters, return values, and othre things that we

    put on stack will be placed in what is sometimes called thread-local storage, i.e., the stack

    of the relevant thread.

    You might also notice how this ruins our beautiful address space layout. Before, the stack

    and heap could grow independently and trouble only arose when you ran out of room in

    the address space. Here, we no longer have such a nice situation. Fortunately, this is

    usually OK, as stacks do not generally have to be very large (the exception being in

    programs that make heavy use of recurison). 

  • 相关阅读:
    Docker手动搭建sentry错误日志系统
    Flask源码解析:Flask应用执行流程及原理
    django Rest Framework---缓存通过drf-extensions扩展来实现
    Python实现 -- 冒泡排序、选择排序、插入排序
    Python查找算法之 -- 列表查找和二分查找
    java设计模式之单例模式
    中文乱码解决方案
    web应用中Filter过滤器之开发应用
    web应用中的Filter过滤器之基础概述
    会话跟踪技术
  • 原文地址:https://www.cnblogs.com/miaoyong/p/4937744.html
Copyright © 2011-2022 走看看