APUE:進程環境,進程控制,進程關係

C程序佈局

在文件中:正文段(機器指令) text,初始化數據段 data,未初始化數據段 bssshell

在內存中:(低地址)text,data,bss,堆(向高地址生長)……(向低地址生長)棧,命令行參數,環境變量(高地址)bash

 

環境變量

char *getenv (const char *__name);
int putenv (char *__string);
int setenv (const char *__name, const char *__value, int __replace);
int unsetenv (const char *__name);
int clearenv (void);

 

退出程序

int atexit (void (*__func) (void));

void exit (int __status);
void _Exit (int __status);
void _exit (int __status);

 

setjmp()和longjmp()

int _setjmp (struct __jmp_buf_tag __env[1]);
void longjmp (struct __jmp_buf_tag __env[1], int __val);

jmp_buf jmpbuffer;

int main() {
	volatile int volaval;					// 內存變量,寄存器變量沒法恢復上下文
	switch(setjmp(jmpbuffer)) {				// label_0
		case 0:								// label_1
			longjmp(jmpbuffer, 1);			// goto label_0, label_2
		case 1:								// label_2
			longjmp(jmpbuffer, 2);			// goto label_0, label_3
		case 2:								// label_3
			// ...
	}
}

 

進程標識

// 進程 ID
__pid_t getpid (void);
// 父進程 ID
__pid_t getppid (void);

// 實際用戶 ID
__uid_t getuid (void);
// root 設置實際用戶 ID、有效用戶 ID、保存的設置用戶 ID;非 root 只設置有效用戶 ID 且 uid 必須等於實際用戶 ID 或保存的設置用戶 ID
int setuid (__uid_t __uid);
// 實際組 ID
__gid_t getgid (void);
// 相似 setuid()
int setgid (__gid_t __gid);
// 有效用戶 ID
__uid_t geteuid (void);
// 設置有效用戶 ID,非 root 時 uid 必須等於實際用戶 ID 或保存的設置用戶 ID
int seteuid (__uid_t __uid);
// 有效組 ID
__gid_t getegid (void);
// 相似 seteuid()
int setegid (__gid_t __gid);
// 交換實際用戶 ID 和有效用戶 ID
int setreuid (__uid_t __ruid, __uid_t __euid);
// 相似 setreuid()
int setregid (__gid_t __rgid, __gid_t __egid);

// 進程組 ID
__pid_t getpgrp (void);
__pid_t getpgid (__pid_t __pid);
// 將 pid 加入 pgid,若是相等表示建立新的進程組
int setpgid (__pid_t __pid, __pid_t __pgid);

 

fork()後子進程繼承父進程的:

  • 打開文件(文件描述符,至關於直接dup,共享同一偏移量)
  • 實際用戶ID、實際組ID、有效用戶ID、有效組ID、附屬組ID
  • 進程組ID、會話ID
  • 控制終端
  • 設置用戶ID標誌和設置組ID標誌
  • 當前目錄和根目錄
  • 文件模式建立屏蔽字(umask)
  • 信號屏蔽和安排
  • 對任意打開文件描述符的的close-on-exec標誌
  • 環境
  • 鏈接的共享存儲段
  • 存儲映像
  • 資源限制

 

exec()系列函數

int execl (const char *__path, const char *__arg, ... /*, NULL */);
int execle (const char *__path, const char *__arg, ... /*, NULL, char *const __envp[] */);
int execlp (const char *__file, const char *__arg, ... /*, NULL */);
int execv (const char *__path, char *const __argv[]);
int execve (const char *__path, char *const __argv[], char *const __envp[]);
int execvp (const char *__file, char *const __argv[]);
int fexecve (int __fd, char *const __argv[], char *const __envp[]);

 

wait()系列函數

#define WIFEXITED(status)
#define WIFSIGNALED(status)
#define WIFSTOPPED(status)
#define WIFCONTINUED(status)

__pid_t wait (__WAIT_STATUS __stat_loc);
__pid_t waitpid (__pid_t __pid, int *__stat_loc, int __options /* = WNOHANG */);
int waitid (idtype_t __idtype /* = P_PID or P_PGID or P_ALL */, __id_t __id, siginfo_t *__infop, int __options);
__pid_t wait3 (__WAIT_STATUS __stat_loc, int __options, struct rusage * __usage);
__pid_t wait4 (__pid_t __pid, __WAIT_STATUS __stat_loc, int __options, struct rusage *__usage);

 

進程調度(優先級)、進程時間

int nice (int __inc);
int getpriority (__priority_which_t __which, id_t __who);
int setpriority (__priority_which_t __which, id_t __who, int __prio);

clock_t times (struct tms *__buffer);

 

解釋器文件

假設解釋器文件內容是:函數

#! /bin/awk -f
...

調用時:佈局

# myscript arg1 arg2

實際調用:ui

# /bin/awk -f myscript arg1 arg2

 

進程組織

  • 會話包含多個進程組,進程組包含多個進程
  • 一個會話有一個控制終端(好比 shell),有一個前臺進程組,多個後臺進程組,只有前臺進程組才能接收到 CTRL+C 之類的信號
  • 終端輸入和產生的信號會向前臺進程組中全部進程發送
  • 做業與會話相似,shell 中用 & 啓動進程時,實際是就是後臺進程組,用 | 管道鏈接時,這條命令中全部進程屬於同一個進程組
相關文章
相關標籤/搜索