用户态 内核态
-1 系统调用/中断/异常会导致进程进入内核态执行-
-操心系统将虚拟空间划分为两部分,一部分为内核空间,一部分为用户空间。针对linux操作系统而言,将最高的1G字节(从虚拟地址0xC0000000到0xFFFFFFFF),供内核使用, 称为内核空间,而将较低的3G字节(从虚拟地址0x00000000到0xBFFFFFFF),供各个进程使用,称为用户空间。
a)用户态内核态区别,程序运行分为ring0~3级别,其中0级别最高,一般的程序运行在3级别,当需要进入内核态进行时,即提高级别访问内核空间。
b)每个进程都会有两个栈,一个内核态栈和一个用户态栈。当执行int中断执行时就会由用户态,栈转向内核栈。系统调用时需要进行栈的切换。
c)1、内核态,运行于进程上下文,内核代表进程运行于内核空间;
2、内核态,运行于中断上下文,内核代表硬件运行于内核空间;
3、用户态,运行于用户空间。
-2 进程的虚拟4G概念和映射概念
+
-3 进程间通信方式
管道-
创建两个管道后fork子进程,其中创建的第一个管道用于读,第二个用于写。如,父进程关闭第一个管道,子进程关闭第二个。父进程写第二个管道后子进程读第一个管道。
此时的读写均是使用系统调用read write。
共享内存-
函数ftok可以理解为根据某个键值生成唯一的key。
对于shmget,创建一个共享区域(共享内存不属于任何一个进程);shmat则是映射到进程地址空间(实际上就是返回一个地址,该地址可写可读),然后使用内存访问接口实现对共享内存的访问。---- 简单来说,就是把共享内存区域(某独立于进程的文件映射到进程的内存空间,然后直接对内存进行读写)。
mmap, 映射文件到进程的进程地址空间,另外一个进程依然。然后对地址的读写会实时反映到对端进程。此时需要同步信号灯等机制保证进程间的同步。
此时的同步一般使用sem_Post sem_wait, 但是要注意的是,多线程编程中的同步一般使用pthread_cond_wait和pthread_cond_signal.
信号-
信号量-
消息队列-
socket-
-3 线程之间的相同通信不必调用内核
net
http://www.ibm.com/developerworks/cn/linux/l-async/
1 五种IO模型
为什么会有五种IO模型,是因为现代操作系统都有缓冲IO,即数据先拷贝到内核IO中,然后再拷贝到用户态的进程IO中。
因此这种方式也就是二IO模式(等待内核缓冲有数据,从内核态拷贝到用户态)
注意:在多路IO复用中,一般设置为NON BLOCK模式,实际上这个指的是socket block,而select语句(或者epoll 等)还是会block的。
当链接数不是很多时,多路IO复用的性能不一定比multi thread+block IO的好,但是多路复用的好处在于,其可以处理多个链接。
2 epoll工作在ET模式的时候,必须使用非阻塞套接口,以避免由于一个文件句柄的阻塞读/阻塞写操作把处理多个文件描述符的任务饿死。?
3 支持的socket数目:它所支持的FD上限是最大可以打开文件的数目,这个数字一般远大于2048,举个例子,在1GB内存的机器上大约是10万左 右,具体数目可以cat /proc/sys/fs/file-max
僵尸进程 :假设A是B的父进程,B挂的时候A没有使用wait或者waitpid回收B的资源,则B占用进程描述符,成为了僵尸进程。
孤儿进程 :假设A是B的父进程,A在B之前挂了,则B是孤儿进程。孤儿进程会被init进程托管成为其父进程。
孤儿进程不会影响系统资源,但是僵尸进程会。
如何避免僵尸进程?
1>父进程wait或者waitpid来对子进程回收
2>父进程fork子进程,子进程fork孙子进程之后终止被父进程wait回收,则孙子进程未孤儿进程被init进程托管。
进程状态:运行,就绪,阻塞(内部通过队列来实现),阻塞不占用CPU资源。当然还有初始和终止态。
锁:互斥锁 读写锁 自旋锁 递归锁 需要自己测试
1:加锁失败则挂起,此时可以用trylock函数使得调用线程不阻塞。
2:其中在加锁操作时间片很短时,可以考虑用自旋锁替换互斥锁。
3:读操作很多时可以使用读写锁代替互斥锁。
一般用的锁是互斥锁,比如auto lock这个类,就是在构造函数内以入参这个锁进行加锁(阻塞式加锁),析构函数内解锁,放在函数入口处,对函数进行加锁。比如PV原语,消息收发逻辑中使用到的take give函数,其实现:
定义一个互斥锁一个条件变量,在give操作中先使用autolock然后自加条件变量值再pthread_cond_signal;take则是先加锁,然后若条件变量值不满足条件则pthread_cond_wait释放锁并且挂起,最后获取到锁的时候重新加锁,自减条件变量并且释放锁。这里用到的锁也互斥锁。
fread和read等的区别:
1. fread属于标准库,read系列是系统调用。其中fread内部调用了read。
2. fread里面使用到的标准输入输入为stdin等,而read使用的标准输入输出为STDIN_FILENO.
3.fread函数族属于标准I/O,使用的头文件为#incude<stdio.h>,定义一个FILE对象进行使用;而read等系统调用使用的头文件为#include<unistd.h>,属于没有buffer的I/O,使用到的文件标识为STDIN_FILENO为非负整数。
4.fread是标准C定义的,而read是POSIX定义的
5.如果使用fread,fread在用户态用缓存,使用减少了和内核态的交互操作。而read没有缓存,直接执行系统调用。
简言之
fread 标准函数 用户态缓冲 文件指针 C函数库
read 系统调用 无缓冲(无用户态缓冲) 文件句柄 POSIX
还有其他类似的函数
题目:http://www.cnblogs.com/memewry/archive/2012/08/25/2656966.html
链路层:通过各种控制协议,将有差错的物理信道变为无差错的、能可靠传输数据帧的数据链路。
物理层:利用传输介质为数据链路层提供物理连接,实现比特流的透明传输。