ch02:进程

 
第二讲 进程
内核跟踪进程的下列信息
运行的位置
访问的文件
信用状(安全机制)
当前目录
访问的内存空间
1.进程的属性
pid
       基本属性pid(进程标识符)和ppid
       pid_t getpid() // 获得本进程的进程id
       pid_t getppid() // 在子进程中执行它,获得父进程的进程id
       举例
       #include <stdio.h>
#include <sys/types.h>
 
int main(int argc, char*argv[])
{
              pid_t id = getpid();
              printf("this id num %d/n",id);
              return 0;
}
[root@localhost ch01]# gcc –o getpid getpid.c
[root@localhost ch01]# ./getpid
This id num 1991
 
信用状(安全机制)
       etc/passwd、etc/group
       int setgroups(size_t num, const gid_t *list)
       int getgroups(size_t num, gid_t *lsit)
      
setuid/setgid和系统守护进程
       什么是守护进程
       real uid、saved uid、effective uid
       int setreuid(uid_t ruid, uid_t euid) // BSD提出
       int setuid(uid_t euid) // Posix标准
uid和gid总结
       出错返回-1,正确执行时返回0
在大部分函数原形在unistd.h中定义
int setreuid(uid_t ruid,uid_t euid) // 设置当前进程的真实用户标示符为ruid,以及进程的有效// 用户标示符为euid
int setrgid(gid_t rgid, gid_t egid) // 设置当前进程的真实组标示符为ruid,以及进程的有效组
//标示符为euid
 
int setuid(uid_t uid) // 如果是普通用户调用,则将进程的有效用户标示符设置为uid
                     // 如果是root用户调用,则将真实、有效和已保存的用户标示符设置为uid
itn setgid(gid_t gid) // 如果是普通用户调用,则将进程的有效用户组标示符设置为uid
                     // 如果是root用户调用,则将真实、有效和已保存的用户组标示符设置为uid
int seteuid(uid_t gid) 等价于setreuid(-1,euid)
int setegid(gid_t gid) 等价于setrgid(-1,egid)
int setgroups(size_t num, const gid_t *list) // 把当前进程的补充组设为list
   函数原型在grp.h中
uid_t getuid() // 返回进程的真实用户标示符
uid_t geteuid() // 返回进程的有效用户标示符
gid_t getgid() // 返回进程的真实组标示符
gid_t getegid() // 返回进程的有效组标示符
size_t getgroups(size_t size, gid_t list[]) // 将当前进程的补充组返回到list中
函数原形在grp.h中
2.进程相关信息
程序参数
int main(int argc ,char *argv[])
extern char *environ[] // 全局变量,指向环境变量中的每个元素。声明在<usrstd.h>中
const char *getenv(const char *name) // 如果这个值存在,返回指向全局变量中名字为
// name值的指针,否则返回NULL
int putenv(const char *string) // Posix标准定义,具有比较好的移植性
int setenv(const char *name, const char *value, int overwrite) // BSD定义
       例:putenv(“PATH=/bin:/usr/bin”)
              setenv(“PATH”,”/bin:/usr/bin”,1)
资源使用
       int getruseage(int who ,strcut rusage *usage)
       who–RUSAGE_SELF
               RUSAGE_CHILDREN
            RUSAGE_BOTH
       #include <sys/resource.h>
       struct rusage{
        struct timeval ru_utime; // 执行用户代码所用的时间,包括运行用户代码指定的所有
//时间,不包括内核用来完成应用程序请求的
        struct timeval ru_stime; //内核用于系统请求的全部时间,其中不包括在系统调用时
//进程阻塞所花的时间
        long int ru_minflt; // 进程所造成的次要缺陷数
      long int ru_majflt; // 进程照成的主要缺陷数
      long int ru_nswap; // 进程的访问而从磁盘调用内存的页面数
      ……......
}
建立使用限制
       int getrlimit(int resource ,struct rlimit *rlim)
       int setrlimit(int resource,const struct rlimit *rlim)
       struct rlimit
{
              long int rlim_cur; // 软限制值是多少
              long int rlim_max; // 应限制是多少
}
RLIMIT_AS // 进程处于内存的最大数量
RLIMIT_CORE // 由内核生成的core文件的最大大小
RLIMIT_CPU // 全部cpu时间
RLIMIT_DATA // 数据存储的最大容量
RLIMIT_FSIZE // 打开文件的最大数目
RLIMIT_MEMLOCK
RLIMIT_NOFILE // 打开文件的最大数
RLIMIT_NPROC // 进程可以产生的最大子进程数目
RLIMIT_RSS // 可以随时使用的内存容量
RLIMIT_STACK // 堆栈存储区的最大容量
3.进程基本元素
创建子进程
       #include <unistd.h>
       pid_t fork();
       特别之处:返回两次
       举例
       #include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
 
int main(void)
{
              pid_t child;
if (!(child=fork()))
              {
                     printf("/nin child/n");
                     _exit(0);
              }
              printf("in parent -- child is %d/n",child);
              return 0;
}
[root@localhost ch01]# gcc –o forkd forkd.c
[root@localhost ch01]# ./forkd
 
in child
in parent – child is 1918
等待子进程结束
       pid_t wait4(pid_t pid, int *status, int options, struct rusage *rusage);
WIFEXITED(status) //是否正常退出 WEXITSTATUS(status) //返回进程的退出代码
WISIGNALED(status) //是否被信号终止   WTERMSIG(status) // 终止进程的信号的号码
       WIFSTOPPED(status)//进程已被信号终止 WSTOPSIG(status) //返回停止进程的信号
       pid_t wait(int *status)
       pid_t waitpid(pid_t pid, int *status, int options)
       pid_t wait3(int *status, int options ,strcut rusage rusage)
运行新进程
       int execl(const char *path, const char *arg0,….);
       int execlp(const char *file, const char *arg0,…);
       int execle(const char *path, const char *arg0,…);
       int execv(const char *path, const char **argv);
       int execvp(const char *file, const char **argv);
       int execve(const char *file, const char **argv);
       运行成功没有返回;失败返回-1
       execl(“/bin/cat”,”/bin/cat”,”/etc/passwd”, ”/etc/group”, NULL);
       char * argv[] = {“./cat”, ”/etc/passwd”, “/etc/group”, NULL};
       execv(“/bin/cat”, argv);
       char *newenv[] = {“PATH = /bin:/usr/bin”,”HOME=/home/sweethome”,NULL}
       execle(“/usr/bin/env”, ”/usr/bin/env”, NULL, newenv);
       char *argv[]={“/usr/bin/env”, NULL};
       char *newenv[]={“PATH=/bin:usr/bin”, ”HOME=/home/sweethome”, NULL}
       execve(“/usr/bin/env”, argv, newenv);
       execlp(“cat”, “cat”, “/etc/passwd”, “/etc/group”, NULL);
       char *argv[]={“./cat”, “/etc/passwd”, “/etc/group”, NULL};
       execvp(“cat”, argv);
终止
       void exit(int exitcode);
       void _exit(int exitcode);
       int kill(pid_t pid, int signum);
4.简单子进程
system()
       int system(const char *cmd) // 首先fork一个exec系列的函数,在这个中运行了一个shell的子程序,然后用这个shell运行cmd命令。原来的程序等待子进程退出,然后返回类似于wait函数的返回。
       /bin/sh
       示例
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
 
int main()
{
              int result;
              result = system("exec ls -l");
              if (!WIFEXITED(result)){
                     printf("abnormal exit/n");
              }
              return 0;
}
[root@localhost ch01]# gcc –o testsystem testsystem.c
[root@localhost ch01]# ./testsystem
总用量 304
-rwx------    1 root     root        11791 5月 16 22:10 a.out
-rwx------    1 root     root          162 5月 21 21:50 ~$ch02.doc
-rwx------    1 root     root        95232 5月 21 21:57 ch02.doc
-rwx------    1 root     root        11791 5月 16 22:11 forkd
-rwx------    1 root     root          218 5月 16 22:09 forkd.c
-rwx------    1 root     root        11649 5月 10 20:32 getpid
-rwx------    1 root     root          144 5月 10 20:32 getpid.c
-rwx------    1 root     root        11693 5月 21 22:05 testsystem
-rwx------    1 root     root          211 5月 21 22:05 testsystem.c
-rwx------    1 root     root            0 5月 21 22:06 test.tmp
-rwx------    1 root     root        94720 5月 16 22:45 ~WRL0001.tmp
-rwx------    1 root     root        94208 5月 21 21:50 ~WRL0003.tmp
-rwx------    1 root     root        94208 5月 21 21:52 ~WRL0005.tmp
-rwx------    1 root     root        95232 5月 21 21:56 ~WRL2785.tmp
-rwx------    1 root     root        94208 5月 21 21:52 ~WRL4030.tmp
从进程读或写
FILE *popen(const char *cmd, const char *mode)
int pclose(FILE *stream);
5.会话和进程组
会话
控制终端
进程组
孤儿进程组
发布了27 篇原创文章 · 获赞 0 · 访问量 7万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章