进程
进程与程序的关系,首先说明一下什么是程序
程序是存放在磁盘上,处于某个目录下的一个可执行文件。程序是静态的,它是一些保存在磁盘上的指令的所有集合。然而程序的实例化被称为进程,进程是linux事物的基本单元。所有进程都拥有自己的独立的处理环境和系统资源。进程的环境由当前系统状态及其父进程信息决定和组成。在Linux环境下第一个进程init由内核产生,以后的进程都是通过fork函数产生的。进程是一个动态的概念,它是程序执行的过程,包括动态创建,调度和消亡的整个过程。
进程的属性
基本属性包括进程号(PID)、父进程号(PPID)、进程组号(PGID)。PID唯一的标识了一个进程,PID是无法在用户层修改的。比如说Linux系统下,系统第一个由内核产生的进程init进程号PID的值是整数1,由fork函数产生的进程的PID依次增加。我们可以通过“ps aux”命令查看系统当前所有进程的基本属性。例如
[root@loclhost ~]#ps aux
USER PID %CPU %MEN VSZ RSS TTY STAT START
root 1 0.0 0.3 1748 572 ? S 04:12
root 2 0.0 0.0 0 0 ? SN 04:12
TIME COMMAND
0:02 init [3]
0:02 [ksofttirgd/0]
我们可以通过getpid()函数获得当前进程的PID。父进程号,任何进程除了init外都是由另一个进程创建的,这个所说的另一进程就是该进程的父进程,被创建的进程也就名正言顺的叫做子进程了。父进程号也是无法在用户层修改的,父进程的进程号在子进程中叫做PPID,用户可以在子进程中通过getppid()函数获得子进程的父进程号。进程组号,在Linux系统下,每个用户都拥有用户号(UID)和用户组号(GUID);和用户管理一样进程也拥有自己的进程号(PID)和进程组号(PGID)。进程组是一个进程和多个进程的集合。他们与同一作业相关,可以接受来自同一终端的信号,每个进程组都有唯一的组号,这个我们是可以通过用户层修改的。哈哈哈哈,我们可以通过getpgid()函数获得进程组号。
用户属性真实的用户号(RUID)、真实用户组号(RGID)、有效用户号(EUID)、有效用户组号(EGID)
进程的状态
进程的整个生命周期可划分为三种状态:
1、执行态:该进程正在占用cpu运行
2、就绪态:进程已经具备执行的一切条件,正在等待分配cpu的处理时间。
3、等待态:进程正在等待某事件的发生
进程控制
fork函数:创建一个新的进程
如下例:
#include
pid_t pid;
pid = fork();
简单的说明一下fork函数:
返回值:在子进程中返回0,父进程中返回子进程ID
一个现有进程可以调用fork函数创建一个新进程。由fork创建的新进程被称为子进程(child process)。fork函数被调用一次但返回两次。两次返回的唯一区别是子进程中返回0值而父进程中返回子进程ID。
子进程是父进程的副本,它将获得父进程数据空间、堆、栈等资源的副本。注意,子进程持有的是上述存储空间的“副本”,这意味着父子进程间不共享这些存储空间,它们之间共享的存储空间只有代码段。
我们可以从这个代码实例中了解到什么:
/* ************************************************************************ * Filename: fork-1.c * Description: * Version: 1.0 * Created: 2010年11月21日 19时18分26秒 * Revision: none * Compiler: gcc * Author: YOUR NAME (wangbaoqi), * Company: * ************************************************************************/
#include <stdio.h> #include <stdlib.h> #include <unistd.h> int main(int argc, char *argv[]) { int num = 10; pid_t pid; pid = fork(); //pid=fork();
if(pid < 0) perror("fork"); if(0 == pid) { num = num+2; printf("This is son procsse is %d,num = %d\n",getpid(),num); } else { num++; printf("this is father process is %d,num=%d\n",pid,num); printf("my id is %d\n",getppid()); } return 0; }
|
/* ************************************************************************ * Filename: fork-2.c * Description: * Version: 1.0 * Created: 2010年11月21日 20时08分16秒 * Revision: none * Compiler: gcc * Author: YOUR NAME (wangbaoqi), * Company: * ************************************************************************/
#include <stdio.h>
#include <stdlib.h> #include <unistd.h> int glob = 6; char buf[] = "a write to stdout\n"; int main(int argc, char *argv[]) { int var; pid_t pid; var = 88; if(write(STDOUT_FILENO,buf,sizeof(buf)-1) != sizeof(buf)-1) printf("write error\n"); printf("before fork"); if((pid = fork())<0) { printf("fork error\n"); } else if(pid == 0) { glob++; var++; } else { sleep(2); } printf("pid=%d,glob=%d,var=%d\n",getpid(),glob,var); return 0; } vfork()函数:创建一个新进程 #include pid_t pid; pid = vfork () 简单的说明一下vfork函数: 返回值:在子进程中返回0,父进程中返回子进程ID vfork()会产生一个新的子进程,其子进程会复制父进程 的数据与堆栈空间,并继承父进程的用户代码,组代码,环 境变量、已打开的文件代码、工作目录和资源限制等。 Linux 使用copy-on-write(COW)技术,只有当其中一 进程试图修改欲复制的空间时才会做真正的复制动作,由于 这些继承的信息是复制而来,并非指相同的内存空间,因此 子进程对这些变量的修改和父进程并不会同步。此外,子进 程不会继承父进程的文件锁定和未处理的信号。注意, Linux不保证子进程会比父进程先执行或晚执行,因此编写 程序时要留意死锁或竞争条件的发生。
|
/* ************************************************************************ * Filename: vfork-1.c * Description: * Version: 1.0 * Created: 2010年11月21日 20时15分15秒 * Revision: none * Compiler: gcc * Author: YOUR NAME (wangbaoqi), * Company: * ************************************************************************/
#include <stdio.h> #include <stdlib.h> #include <unistd.h> int main(int argc, char *argv[]) { pid_t pid; pid = vfork(); if(pid<0) perror("vfork"); if(pid == 0) { sleep(2); printf("This is a child process!%d\n",getpid()); exit(0); } else { printf("This is father process!%d\n",pid); } return 0; }
|
/* ************************************************************************ * Filename: vfork-2.c * Description: * Version: 1.0 * Created: 2010年11月21日 20时28分00秒 * Revision: none * Compiler: gcc * Author: YOUR NAME (wangbaoqi), * Company: * ************************************************************************/
#include <stdio.h> #include <stdlib.h> #include <unistd.h> int main(int argc, char *argv[]) { pid_t pid; int num = 100; pid = vfork(); if(pid<0) perror("vfork"); if(0 == pid) { sleep(2); num++; printf("This is child process: pid=%d,num=%d\n",getpid(),num); num = num+13; exit(0); } else { printf("This is father process: pid=%d,num=%d\n",pid,num); }
return 0; }
|
阅读(1704) | 评论(1) | 转发(1) |