Chinaunix首页 | 论坛 | 博客
  • 博客访问: 366503
  • 博文数量: 50
  • 博客积分: 1495
  • 博客等级: 上尉
  • 技术积分: 805
  • 用 户 组: 普通用户
  • 注册时间: 2010-12-21 14:19
文章分类

全部博文(50)

文章存档

2011年(47)

2010年(3)

分类: LINUX

2011-04-07 16:21:37

008_进程控制-01

 

1)       进程标识

每个及昵称都有一个非负整型的唯一进程ID

专用进程:

    进程ID 0是调度基础,常常被称为交换进程(swapper)

    进程ID 1 init进程。

 

2)       fork()函数

一个现存进程调用fork函数是UNIX内核创建一个新进程的唯一方法。

注意:fork不适用于交换进程、init进程和页精灵进程。

 

子进程和父进程继续执行fork之后的指令。子进程是父进程的复制品。

子进程获得了父进程数据空间、堆和栈的复制品。但是注意这是子进程所拥有的拷贝。父子进程并不贡献这些存储空间部分。如果正文段是只读的,则父子进程共享正文段。

 

写个程序证实这点:

  1. int main(void)

  2. {

  3.     pid_t pid;

  4.     int num = 6;

  5.  

  6.     pid = fork();

  7.     if (pid < 0) {

  8.         perror("fork()");

  9.     } else if (pid == 0) {

  10.         num++;

  11.         printf("I am child process, ID is %d, num = %d\n", getpid(), num);

  12.     } else {

  13.         sleep(2);

  14.         printf("I am parent process, ID is %d, num = %d\n", getpid(), num);

  15.     }

  16.  

  17.     exit(0);

  18. }

 fork.txt   

OUTPUT

cjok@ubuntu:~/c/process$ ./fork

I am child process, ID is 4353, num = 7

I am parent process, ID is 4352, num = 6

 

从输出不难看出,子父进程并没有共享num变量。

 

    讨论下父子进程同时对一个文件进行读写操作,会用什么现象?

   

  1. int main(void)

  2.    {

  3.     pid_t pid;

  4.     int fd;

  5.     char buf[20];

  6.     memset(buf, '\0', 20);

  7.  

  8.     fd = open("./test.txt", O_RDWR | O_CREAT |O_APPEND, 0664);

  9.     if (fd == -1) {

  10.         perror("./test.txt");

  11.         exit(-1);

  12.     }

  13.  

  14.     pid = fork();

  15.     if (pid < 0) {

  16.         perror("fork()");

  17.         exit(-1);

  18.     } else if (pid == 0) {

  19.         write(fd, "HELLO ", 6);

  20.         //sleep(1); /* 延迟1秒,目的是使父进程先结束 */

  21.     } else {

  22.         write(fd, "CJOK", 4);

  23.     }

  24.  

  25.     lseek(fd, 0, SEEK_SET);

  26.     read(fd, buf, 20);

  27.     printf("%s\n", buf);

  28.     exit(0);

  29. }

 

当把sleep注释掉时,输出是

  1. cjok@ubuntu:~/c/process$ ./fork_file

  2. HELLO

  3. HELLO CJOK

打开文件test.txt,其中内容是HELLO CJOK 是我想要的结果。

  fork_file.txt   

但是添加sleep时,输出是

  1. cjok@ubuntu:~/c/process$ ./fork_file

  2. CJOK

  3. cjok@ubuntu:~/c/process$ CJOKHELLO

文件中的内容是 CJOKHELLO

 

怎么会出现这样的情况呢?

子进程虽然复制了父进程的资源,但是磁盘上的文件却没有复制,子父进程最终都要把数据写到同一个文件中。谁先写谁慢写都会导致文件中的内容不同。

 

 

 

3)       f o r k之后处理文件描述符有两种常见的情况:

a)       父进程等待子进程完成。在这种情况下,父进程无需对其描述符做任何处理。当子进程终止后,它曾进行过读、写操作的任一共享描述符的文件位移量已做了相应更新。

b)       父、子进程各自执行不同的程序段。在这种情况下,在f o r k之后,父、子进程各自关闭它们不需使用的文件描述符,并且不干扰对方使用的文件描述符。这种方法是网络服务进程中经常使用的。

 

除了打开文件之外,很多父进程的其他性质也由子进程继承:

实际用户I D、实际组I D、有效用户I D、有效组I D

添加组I D

进程组I D

对话期I D

控制终端。

设置-用户- I D标志和设置-- I D标志。

当前工作目录。

根目录。

文件方式创建屏蔽字。

信号屏蔽和排列。

对任一打开文件描述符的在执行时关闭标志。

环境。

连接的共享存储段。

资源限制。

 

父、子进程之间的区别是:

fork的返回值。

进程I D

不同的父进程I D

子进程的t m s u t i m e , t m s s t i m e , t m s c u t i m e以及t m s u s t i m e设置为0

父进程设置的锁,子进程不继承。

子进程的未决告警被清除。

子进程的未决信号集设置为空集。

 

4)       f o r k有两种用法:

a)       一个父进程希望复制自己,使父、子进程同时执行不同的代码段。这在网络服务进程中是常见的——父进程等待委托者的服务请求。当这种请求到达时,父进程调用f o r k,使子进程处理此请求。父进程则继续等待下一个服务请求。

b)       一个进程要执行一个不同的程序。这对s h e l l是常见的情况。在这种情况下,子进程在从f o r k返回后立即调用e x e c

 

5)       fork失败的两个主要原因:

a)       系统中已经有太多的进程;

b)       该实际用户ID的进程总数超过了系统的限制。

 

 

水平有限,如果有错误的地方,请指正,thanks

cjok.liao@gmail.com


 

 

 

 

阅读(1113) | 评论(0) | 转发(0) |
0

上一篇:007_UNIX进程的环境

下一篇:Linux C Coding style

给主人留下些什么吧!~~