[Java Concurrency in Practice]1.1.A (Very) Brief History of Concurrency

1.1. A (Very) Brief History of Concurrency
关于并发历史的简短描述
In the ancient past, computers didn't have operating systems; they executed a single program from beginning to end, and that program had direct access to all the resources of the machine. Not only was it difficult to write programs that ran on the bare metal, but running only a single program at a time was an inefficient use of expensive and scarce computer resources.
在计算机刚刚被发明使用的年代,还没有操作系统的概念。这个时候的计算机从头到尾执行每一个单独的程序。在程序在执行过程中,直接访问计算机的硬件资源。由于直接面向硬件编程,编写程序是非常困难的。而且在同一时间只能只能有一个程序来独占相对昂贵的、稀缺的计算资源是非常低效的。
Operating systems evolved to allow more than one program to run at once, running individual programs in processes: isolated, independently executing programs to which the operating system allocates resources such as memory, file handles, and security credentials. If they needed to, processes could communicate with one another through a variety of coarse-grained communication mechanisms: sockets, signal handlers, shared memory, semaphores, and files.
操作系统的出现改善了这一个困境,它开始允许在同一时间运行多个程序。在进程中运行彼此独立的程序(进程:能够彼此隔离的,独立的执行程序,这些程序所需要的诸如内存、文件句柄、安全认证等资源由操作系统为其分配)。如果需要,进程应该能够使用一些粗粒度的通讯机制在彼此之间互相通讯,这些通讯机制包括:socket、信号处理、共享内存、信号量以及文件等。
Several motivating factors led to the development of operating systems that allowed multiple programs to execute simultaneously:
如下这些因子激发了操作系统必须允许多个程序同时运行。
Resource utilization. Programs sometimes have to wait for external operations such as input or output, and while waiting can do no useful work. It is more efficient to use that wait time to let another program run.
资源利用。程序有时候必须等待外部操作比如输入输出等。并且这种等待通常不能够做有用的工作。因此使用这些等待的时间允许别的程序运行时更有意义的。
Fairness. Multiple users and programs may have equal claims on the machine's resources. It is preferable to let them share the computer via finer-grained time slicing than to let one program run to completion and then start another.
公平。多个用户或者程序对硬件资源应该具有公平的请求权限。因此对于从头到尾完整的运行一个程序这种使用模式而言,允许每个程序获得良好分割的时间片无疑是一种更好的选择。
Convenience. It is often easier or more desirable to write several programs that each perform a single task and have them coordinate with each other as necessary than to write a single program that performs all the tasks.
便利。编写几个程序,每个程序完成一个功能,每个程序根据需要进行合作比编写一个程序完成所有功能通常更加简单和可取。
In early timesharing systems, each process was a virtual von Neumann computer; it had a memory space storing both instructions and data, executing instructions sequentially according to the semantics of the machine language, and interacting with the outside world via the operating system through a set of I/O primitives. For each instruction executed there was a clearly defined "next instruction", and control flowed through the program according to the rules of the instruction set. Nearly all widely used programming languages today follow this sequential programming model, where the language specification clearly defines "what comes next" after a given action is executed.
在早期的时间共享的系统中,每隔一进程就是一台虚拟的冯•诺依曼机。它使用单独的内存空间来存储指令和数据,根据机器语言的语义顺序执行指令,通过操作系统级别的IO通道与外部世界交互。对于每一条执行完毕的指令,都有一条定义清晰的下一条指令。根据指令集的规则控制程序。当今几乎所有被广泛使用的语言都遵循这种程序模式,即:语言规范清楚的定义在一个给定的动作完毕之后,后续要执行的动作。
The sequential programming model is intuitive and natural, as it models the way humans work: do one thing at a time, in sequencemostly. Get out of bed, put on your bathrobe, go downstairs and start the tea. As in programming languages, each of these real-world actions is an abstraction for a sequence of finer-grained actionsopen the cupboard, select a flavor of tea, measure some tea into the pot, see if there's enough water in the teakettle, if not put some more water in, set it on the stove, turn the stove on, wait for the water to boil, and so on. This last step waiting for the water to boil also involves a degree of asynchrony. While the water is heating, you have a choice of what to dojust wait, or do other tasks in that time such as starting the toast (another asynchronous task) or fetching the newspaper, while remaining aware that your attention will soon be needed by the teakettle. The manufacturers of teakettles and toasters know their products are often used in an asynchronous manner, so they raise an audible signal when they complete their task. Finding the right balance of sequentiality and asynchrony is often a characteristic of efficient people and the same is true of programs.
顺序编程模式是非常直观和自然的,因为它符合人类的工作模式:先做一件事情,然后做下一件。起床,穿上浴衣,下楼,开始喝茶。在编程语言中,每一件现实世界中的动作都被抽象成细小粒度的行为。选择适合口味的茶,量取茶叶放入壶中,看看烧水壶中是否有足够的水,如果没有的话则放入水,把烧水壶放到火炉上。打开火炉,等待水沸腾,等等。最后一步等待水沸腾的过程同时也牵扯到一定程度的异步操作。当水被加热的时候,你可以选择做什么事情,只是去等待,或者利用这段时间去烤面包(另外一个异步任务),或者打开报纸,并且随时留意开水壶的情况。开水壶和烤炉的生产厂商知道他们的商品通常是以异步的方式被使用,所以他们增加的声音信号以表示任务的完成。寻找顺序执行和异步执行之间的平衡是一个高效率人士的特性,这一点同样可以用在程序身上。
The same concerns (resource utilization, fairness, and convenience) that motivated the development of processes also motivated the development of threads. Threads allow multiple streams of program control flow to coexist within a process. They share process-wide resources such as memory and file handles, but each thread has its own program counter, stack, and local variables. Threads also provide a natural decomposition for exploiting hardware parallelism on multiprocessor systems; multiple threads within the same program can be scheduled simultaneously on multiple CPUs.
激发进程出现的诱因同样也激发出了线程的出现。线程允许多个程序控制流在同一个进程中出现。他们能够共享进程内资源,例如内存、文件句柄。但是每一个线程都拥有属于自己的程序计数器、栈、以及本地变量。线程通常能够为在多处理器系统上开发硬件并行的程序提供自然分解。同一个程序中的多个线程可以被多cpu同时调度。
Threads are sometimes called lightweight processes, and most modern operating systems treat threads, not processes, as the basic units of scheduling. In the absence of explicit coordination, threads execute simultaneously and asynchronously with respect to one another. Since threads share the memory address space of their owning process, all threads within a process have access to the same variables and allocate objects from the same heap, which allows finer-grained data sharing than inter-process mechanisms. But without explicit synchronization to coordinate access to shared data, a thread may modify variables that another thread is in the middle of using, with unpredictable results.
线程有时候也会被称为轻量级的进程,大多数的现代把线程(而不是进程)当做基本的调度单位。在没有显式的调度的情况下,多个线程同时、异步执行。由于线程共享其所在进程的内存空间,一个进程中的所有线程可以访问相同的变量,而且可以从相同的对内存中创建对象,这意味着可以实现比进程间机制更细粒度的数据共享。但是在没有显式同步机制调度访问共享数据的情况下,一个线程可能会改变两外一个线程正在使用的数据,从而导致无法预计的后果。

你可能感兴趣的:([Java Concurrency in Practice]1.1.A (Very) Brief History of Concurrency)