不管你用了多少技术,框架,模式,实现了怎么样的协议与功能,原理是什么,也只是人类意识层面上的内容,到底层只有指令。
用到的一些应用软件,MYSQL?REDIS?也只是程序。运行于计算机之上的这一切都只是程序。这些程序经过指定的步骤,从高级到低级,从人类可以理解到无法识别,最终转换为计算机可以识别的指令。
我们编写的所有的源代码,最终都要转换成计算机系统可以识别的内容,而计算机系统包括硬件以及运行其上的系统软件。 我们所有的编码,都是面向指定的语法,而这门语言本身,则是面向操作系统的,因为外部软件通常是不能直接操纵硬件资源,需要借助于操作系统。 所以某种程度上可以这样认为,所有的源代码都是面向语言的,而语言本身面向操作系统。
不管是进程还是线程,都是操作系统对于程序执行的抽象描述,是相关数据:寄存器状态、堆栈值等所有相关数据的集合。
通过进程的相关信息的维护管理,操作系统保障多道程序可以顺利的切换执行;进程之间的是怎么进行交互的呢?通过TCP/IP的端口来实现。这就是RPC,微服务框架等等的实现了。
而对于多线程的应用程序,需要开发者对线程的数据等相关信息进行控制,以保证多线程间可以正确的运行。
多线程共享进程资源,而有些资源是互斥的,并不能允许同时访问,比如对计数器+1,如果临界区代码可以同时访问,可能两个人同时过来,每个人同时从1开始执行加1操作,结果却是2,这显然是不正确的 多线程编程需要解决的核心就是互斥资源的访问以及如何高效的利用CPU。
保障资源的互斥访问是为了保证程序的正确性,否则再快的程序也没有意义;如果编写的程序非常的不合理,逻辑不清晰,反而可能会带来性能问题,而不是提高效率。
线程之间又是怎样进行交互?线程的通信就比较简单,有一大块共享的内存,只要大家的指针是同一个就可以看到各自的内存。
线程描述符:
union thread_union {
struct thread_info thread_info;
unsigned long stack[2048]; /* 1024 for 4KB stacks */
};
struct thread_info {
struct task_struct *task; /* main task structure */
struct exec_domain *exec_domain; /* execution domain */
unsigned long flags; /* low level flags */
unsigned long status; /* thread-synchronous flags */
__u32 cpu; /* current CPU */
__s32 preempt_count; /* 0 => preemptable, <0 => BUG */
mm_segment_t addr_limit; /* thread address space:
0-0xBFFFFFFF for user-thead
0-0xFFFFFFFF for kernel-thread
*/
struct restart_block restart_block;
unsigned long previous_esp; /* ESP of the previous stack in case
of nested (IRQ) stacks
*/
__u8 supervisor_stack[0];
};