Chinaunix首页 | 论坛 | 博客
  • 博客访问: 37756
  • 博文数量: 41
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 357
  • 用 户 组: 普通用户
  • 注册时间: 2014-04-20 16:26
文章分类

全部博文(41)

文章存档

2014年(41)

我的朋友

分类: LINUX

2014-05-04 12:23:26

 进程是linux的一种并行运行机制,一个进程可以通过fork()或vfork函数创建另一个进程,fork函数有两个返回值,在子进程(后面创建的那个)中其返回值为0,在父进程(原来的那个)中其值大于0,这个大于0的值就是子进程的pid(进程的标识符),我们通常通过这种方法判断他们是子进程还是父进程。
  8 #include
  9 #include
 10 #include
 11 #include
 12
 13 int main()
 14 {
 15     pid_t pid;
 16
 17     if((pid = fork()) == -1)
 18     {
 19         perror("fork");
 20         exit(1);
 21     }
 22
 23     if(pid == 0)
 24     {
 25         printf("child: %d , ppid: %d\n", getpid(), getppid());
 26         return 0;
 27     }
 28     else
 29     {
 30         printf("praent: %d, child pid %d\n", getpid(), pid);
 31         if((pid = fork()) == -1)
 32         {
 33             perror("fork");
 34             exit(1);
 35         }
 36
 37         if(pid == 0)
 38         {
 39             printf("child: %d , ppid: %d\n", getpid(), getppid());
 40         }
 41         else
 42         {
 43             printf("praent: %d, child pid %d\n", getpid(), pid);
 44             waitpid(-1,NULL,0);
 45             waitpid(-1,NULL,0);
 46         }
 47     }
 48
 49     return 0;
 50 }

子进程创建之后继承父进程的大部分空间(如变量、文件描述符、当前目录等).子进程可以通过
exec族的函数加载其它的程序到这个空间,以运行其它的程序。Exec族的函数有以下5个,各有一些不同

       int execl(const char *path, const char *arg, ...);

       int execlp(const char *file, const char *arg, ...);

       int execle(const char *path, const char *arg, ..., char * const envp[]);

       int execv(const char *path, char *const argv[]);

       int execvp(const char *file, char *const argv[]);

子进程结束时可使用exit函数退出,父进程在子进程可使用waitwaitpid函数等待子进程退出,以接收子进程退出的状态,释放子进程的全部空间。

僵尸进程:子进程结束了可是父进程还没有调用wait函数接收子进程结束状态,此时子进程处于僵尸态,成为僵尸进程。

孤儿进程:子进程还没结束,父进程先结束了,此时子进程称为孤儿进程。孤儿进程由init进程领养。
  8 #include
  9 #include
 10 #include
 11 #include
 12
 13
 14 int main()
 15 {
 16     pid_t pid;
 17     pid = fork();
 18     if(pid == 0)
 19     {
 20         printf("inclild\n");
 21         sleep(5);
 22         exit(0);
 23     }
 24     else
 25     {
 26         wait(NULL);
 27         printf("parent\n");
 28     }
 29     return 0;
 30 }
 31

进程有uidgidpideuid等属性,可通过getuidgetpgrdgetpidgeteuid等函数来获取。

进程访问资源的同步可使用互斥锁,信号量来控制。

守护进程:

创建步骤:

Fork创建一个进程

父进程退出

Setsid新建会话

Umask设置文件权限掩码

关闭文件描述符

012号文件描述符绑定到/dev/null

改变当前目录为根目录
  8 #include
  9 #include
 10 #include
 11 #include
 12 #include
 13 #include
 14 #include
 15 #include
 16
 17
 18 int main()
 19 {
 20 #if 1
 21     pid_t pid;
 22     pid = fork();
 23     if(pid < 0)
 24     {
 25         perror("fork");
 26         exit(1);
 27     }
 28     else if(pid > 0)
 29         exit(0);
 30
 31     while(getppid() != 1);
 32     if(setsid() == -1)
 33     {
 34         perror("setsid");
 35         exit(0);
 36     }
 37     umask(0);
 38 #if 1
 39     struct rlimit rlim;
 40     if(getrlimit(RLIMIT_NOFILE,&rlim) == -1)
 41     {
 42         perror("getrlimit");
 43         exit(1);
 44     }
 45
 46     int i;
 47     for(i=0; i  48         close(i);
 49     if((i = open("/dev/null",O_RDONLY)) == -1)
 50     {
 51         perror("open");
 52         exit(0);
 53     }
 54     dup2(i,0);
 55     dup2(i,1);
 56     dup2(i,2);
 57 #endif
 58     if(chdir("/") == -1)
 59     {
 60         perror("chdir");
 61         exit(0);
 62     }
 63 #endif
 64     time_t t;
 65     while(1)
 66     {
 67         time(&t);
 68         printf("\33[s\33[1;80H%s\33[u", (char *)ctime(&t));
 69         sleep(1);
 70     }
 71 }

阅读(290) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~