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.會話和進程組
會話
控制終端
進程組
孤兒進程組
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.