三态模型 运行状态 当一个进程在处理机上运行时,则该进程处于运行状态。处于次状态的进程的数目小于等于处理器的数目,在单处理系统中,处于运行态的进程只有一个。 就绪状态 当一个进程获得了除CPU以外的任何资源,一旦获得CPU,便可立即执行,则该进程处于就绪状态。一个系统中处于就绪状态的进程可能有多个,通常它们按优先级排成一个队列,称为就绪队列。 阻塞状态 正在执行的进程由于发生某事件而暂时无法继续执行时,便放弃处理机而处于暂停状态,亦即进程的执行受到阻塞,把这种暂停状态称为阻塞状态,有时也称为等待状态或封锁状态。致使进程阻塞的典型事件有:请求I/O,申请缓冲空间等。通常将这种处于阻塞状态的进程也排成一个队列。有的系统则根据阻塞原因的不同而把处于阻塞状态的进程排成多个队列。 五态模型 对于实际系统,进程的状态和转换更复杂,又引进了新建态和终止态。 新建态 对应于进程刚刚被创建未被提交的状态,等待系统完成创建进程的所有必要信息。进程正在创建过程中,还不能运行。操作系统在创建状态要进行的工作包括分配和建立PCB、建立资源表格(如打开文件表) 继续阅读 >>


杜肖孟 16/07/30 10:11:45
pid_t pid; printf("hello "); pid=fork(); printf("world "); 执行结果是打印了两行 hello world 问题出现在 printf ,它是有数据缓冲区的,不加  \n 数据不刷新 fork()创建子进程时,复制了父进程的数据段和堆栈段,包括上面所讲的缓冲区,在执行后面的 printf ,就打印了两遍hello world. pid_t pid; printf("hello \n"); //fflush(stdout); pid=fork(); printf("world "); 这段代码的执行结果是  hello hello world 如果加上 \n 后,换行符会刷新缓冲区,将 hello 输出,printf 数据缓冲区被洗,fork()执行完,打印两次 world 就结束了。fflush(stdout) 和 \n 效果相同。 这是为什么呢? 这是由【设备的不同缓冲属性】决定的。 继续阅读 >>


杜肖孟 16/07/29 22:23:01
进程与线程是什么?   进程是并发执行的程序在执行过程中分配和管理资源的基本单位,是一个动态的实体。每个进程有自己独立的地址空间。附:程序是静态的,是一些保存在硬盘上的可执行代码,是指令的集合。   线程是进程的一个实体,是操作系统分配CPU时间的基本单位,是计算机中独立运行的最小单位,与同属一个进程的其他线程共享进程的全部资源。线程在进程内部共享地址空间、打开的文件描述符等资源,但是线程也有私有数据信息,如寄存器(包括程序计数器和堆栈指针)、堆栈等。 主要区别:进程和线程的主要差别在于它们是不同的操作系统资源管理方式。进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不同执行路径,线程没有独立的运行空间,线程的并发度好。一个程序至少有一个进程,一个进程至少有一个线程。 多线程的优点 1. 创建一个新的进程时要耗费时间为其分配系统资源,而创建一个新的线程花费的时间则要少很多。 2. 线程间的切换速度要远远快过进程间的切换速度。 3.线程间的通信更加方便和省时,一个线程的数据可以直接提供给其 继续阅读 >>


杜肖孟 16/07/29 15:02:27
1、特权级 Intel x86架构的cpu一共有0~4四个特权级,0级最高,3级最低,硬件上在执行每条指令时都会对指令所具有的特权级做相应的检查。硬件已经提供了一套特权级使用的相关机制,软件自然要好好利用,这属于操作系统要做的事情,对于UNIX/LINUX来说,只使用了0级特权级别和3级特权级。也就是说在UNIX/LINUX系统中,一条工作在0级特权级的指令具有了CPU能提供的最高权力,而一条工作在3级特权的指令具有CPU提供的最低或者说最基本权力 2、用户态和内核态 内核栈:Linux中每个进程有两个栈,分别用于用户态和内核态的进程执行,其中的内核栈就是用于内核态的堆栈,它和进程的task_struct结构,更具体的是thread_info结构一起放在两个连续的页框大小的空间内。 现在我们从特权级的调度来理解用户态和内核态就比较好理解了,当程序运行在3级特权级上时,就可以称之为运行在用户态,因为这是最低特权级,是普通的用户进程运行的特权级,大部分用户直接面对的程序都是运行在用户态;反之,当程序运行在0级特权级上时,就可以称之为运行在内核态。 继续阅读 >>


杜肖孟 16/07/29 11:46:19
  标准输出指的是命令执行所传回的正确的信息,而标准错误输出可理解为命令执行失败后,所传回的错误信息。   标准输出(stdout)和标准错误输出(stderr),默认都是输出到屏幕上来,数据流重定向可以将stdout和stderr分别传送到其他的文件或设备去。   分别传送所用的特殊字符如下:  stdin:0,使用 < 或 <<  stdout:1,使用 > 或 >> 注:仅存在>时,代表默认的代码1  stderr:2,使用2> 或 2>> 例如执行命令:ll /home > ~/testfile 屏幕上无任何信息,因为原本“ll /home”显示的数据被重新导向~/testfile文件中了。 文件创建方式: 若以 > 输出到一个已经存在的文件中,那么这个文件就会被覆盖,若不存在,系统就会自动创建。与 >> 的区别是,>> 不会覆盖,而是在最下方累加进去。stderr 同理 例如:执行find命令经常会由于权限的原因产生错误信息. 继续阅读 >>


杜肖孟 16/07/28 17:12:35
咱们从普通用户修改密码说起。 我们知道linux用户修改密码,最终修改的是/etc/shadow这个文件。可是我们用 ll /etc/shadow命令查看会发现此文件的权限为000,如下图: 也就是说,非root用户对此文件没有任何权限。 那矛盾就产生了:linux普通用户是有权限修改自己密码的,而普通用户又不俱备对/etc/shadow这个文件的任何权限。 linux操作系统为了解决这一问题,就产生了setUID权限。 我们了解在linux系统下,用户修改密码(也就是修改/etc/shadow文件)是通过passwd(此命令文件的绝对路径为/usr/bin/passwd,可以通过which passwd查看)这个命令的。我们用ll /usr/bin/passwd看一下此命令文件的权限,如下图: 发现/usr/bin/passwd的权限为:-rwsr-xr-x. 1 root root 在此“文件所有者”的第三位是s权限,也就是咱们本文提到的setUID权限。 回到咱们上面提出的问题,普通用户是怎么修改权限的。普通用户对/etc/shadow 继续阅读 >>


杜肖孟 16/07/28 11:33:57
编译器函数库自带的快速排序函数。 qsort()的函数原型是 void qsort(void*base,size_t num,size_t width,int(__cdecl*compare)(const void*,const void*)); 各参数:1 待排序数组首地址 2 数组中待排序元素数量 3 各元素的占用空间大小 4 指向函数的指针 例1:对一个长为1000的数组进行排序时,int a[1000];  qsort(a,1000,sizeof(int),comp); 其中comp函数应写为: 1 2 3 4 int comp(const void*a,const void*b) { return *(int*)a-*(int*)b; } 例2: 对一个二维数组进行排序: int a[1000][2];   1 2 3 4 5 6 7 qsort(a,1000,sizeof(int) 继续阅读 >>


杜肖孟 16/07/27 16:30:41
S_ISLNK(st_mode):是否是一个连接. S_ISREG是否是一个常规文件. S_ISDIR是否是一个目录S_ISCHR是否是一个字符设 备. S_ISBLK是否是一个块设备 S_ISFIFO是否 是一个FIFO文件. S_ISSOCK是否是一个SOCKET文件  man 2 stat ...  struct stat {              dev_t st_dev;                                 &nbs 继续阅读 >>


杜肖孟 16/07/27 08:16:36
linux系统提供了详细的帮助手册,我看到 man 2 link  这一命令,对中间的  2 感到一些疑惑,就在网上查了一下,分享给大家。 man手册分为多个section,每个section用一个字符表示。 这里的section可以理解为类别,例如:man 1 passwd 和 man 5 passwd是不一样的类别(详细见表)。通常我们使用man passwd,这个时候man就按照预先设置的搜索路径和顺序去搜索passwd,当搜索到一个就停止继续搜索并将结果显示出来,如果我们指定了section,那么man只会在指定的section里去查找man帮助页。 作者:Tanswer_ 发表于2016/7/25 14:05:45 原文链接 阅读:13 评论:0 查看评论 继续阅读 >>


杜肖孟 16/07/25 14:05:45
open系统调用 #include <fcntl.h> #include <sys/types.h> #include <sys/stat.h> int open(const char *path,int oflags); int open(const char *path,int oflags, mode_t mode); 简单的说,open建立了一条到文件或设备的访问路径,如果调用成功,它将返回一个可以被read,write和其他系统调用使用的文件描述符。 --------------------------------------------------------------------------------------------------------------------------------------- oflags 参数用于指定打开文件所采取的动作。它是通过必需文件访问模式与其他可选模式相结合的方式来指定的。 必需文件访问模式: O_RDONLY 以只读方式打开 O_WRONLY 继续阅读 >>


杜肖孟 16/07/25 11:38:50