程序:linux
進程shell
#include<unistd.h>
pid_t getpid(void);
pid_t getppid(void);
//pid 的最大值爲32767, 一旦分配到32767 計數器會置爲300從新分配
//pid_max:/proc/sys/kernel/pid_max
// /proc/$PID/status
//pstree
複製代碼
- 文本段(text):包含進程運行的程序指令,只讀,文本段共享,映射到全部使用進程的虛擬地址空間
- 初始化數據包段(data):包含顯式初始化的全局變量和靜態變量
- 未初始化數據包段(BSS段):未初始化的全局變量和靜態變量,啓動前,本段全部內存初始化0;和前者分開的緣由是程序在磁盤存儲時,不須要爲未初始化的變量分配存儲空間
- 棧
- 堆
$ size a.out
text data bss dec hex filename
1317 500 24 1841 731 a.out
// + + =
複製代碼
extern char etext, edata, end;
複製代碼
程序的局部性編程
- 空間局部性:程序傾向訪問訪問過內存地址附近的內存
- 時間局部性:程序傾向訪問已經訪問過的內存
內核爲進程分配和釋放頁表bash
進程虛擬地址空間頁——頁表——RAM頁幀數據結構
32位通常虛擬內存每頁4K, 64位?佈局
子進程繼承父進程環境變量,並隔離ui
/proc/$PID/environ 複製代碼
#include<stdlib.h> extern char **environ; char *getenv(const char *name); int putenv(char *string); // string 指向 'name=value'的字符串 修改string 會影響environ int setenv(const char *name, const char *value, int overwrite); // 將 name, value 分配至內存緩衝區,以後修改不會影響environ int unsetenv(const char *name); 複製代碼
環境不只能夠做爲進程間通信;還能夠做爲程序間通信的方式spa
#include<setjmp.h>
int setjmp(jmp_buf env);
void longjmp(jmp_buf env, int val);
// 調用setjmp 時,把當前進程環境的各類信息,和程序計數器(指向代碼)和棧指針寄存器的信息的副本保存到env
register int rvar;
volatile int vvar;
複製代碼
- program break 開始位於 &end
#include <unistd.h>
int brk(void *end_data_segment);
//Returns 0 on success, or –1 on error
//設置 program break 到 end_data_segment 會根據頁四捨五入取整
void *sbrk(intptr_t increment);
//Returns previous program break on success, or (void *) –1 on error
//設置 program break 增長 increment
複製代碼
#include<stdlib.h>
#include<malloc.h>
void *malloc(size_t size);
//Returns pointer to allocated memory on success, or NULL on error 不初始化內存
void free(void *ptr);
// free通常不會下降program break, 可是當棧頂的空閒內存足夠大,free的glibc實現會調用sbrk來下降program break
void *calloc(size_t numitems, size_t size);
//Returns pointer to allocated memory on success, or NULL on error 初始化爲0
void *realloc(void *ptr, size_t size);
//Returns pointer to allocated memory on success, or NULL on error 無連續的內存,拷貝至新內存
void *memalign(size_t boundary, size_t size);
//Returns pointer to allocated memory on success, or NULL on error 起始地址參數是boundary的整數倍
複製代碼
#include <alloca.h>
void *alloca(size_t size);
//Returns pointer to allocated block of memory
複製代碼
Linux 用戶ID能夠不惟一對應多個用戶名unix
#include <pwd.h>
struct passwd {
char *pw_name;
char *pw_passwd;
uid_t pw_uid;
gid_t pw_gid;
char *pw_gecos;
char *pw_dir;
char *pw_shell;
};
struct passwd *getpwnam(const char *name);
struct passwd *getpwuid(uid_t uid);
//Both return a pointer on success, or NULL on error; see main text for description of the 「not found」 case
// 返回的指針指向靜態內存,不可重入(not reentrant)
複製代碼
#include <grp.h>
struct group {
char *gr_name;
char *gr_passwd;
gid_t gr_gid;
char **gr_mem;
};
struct group *getgrnam(const char *name);
struct group *getgrgid(gid_t gid);
//Both return a pointer on success, or NULL on error; see main text for description of the 「not found」 case
// 返回的指針指向靜態內存,不可重入(not reentrant)
複製代碼
實際用戶/組ID(real xx id)指針
- 進程所屬的用戶組,子進程繼承自父進程
有效用戶/組ID(effective xx id)
一般有效用戶/組ID和實際用戶/組ID相同,可是有兩種方法致使不一樣
xxx
執行set-user-ID 和 set-group-ID的程序
# ls -l prog -rwxr-xr-x 1 root root 302585 Jun 26 15:05 prog # chmod u+s prog //Turn on set-user-ID permission bit # chmod g+s prog //Turn on set-group-ID permission bit # ls -l prog -rwsr-sr-x 1 root root 302585 Jun 26 15:05 prog 複製代碼
會將可執行權限x標識改成s
對於shell腳本無效(38.3補充)
有效用戶ID=0的進程擁有root權限,稱之爲特權級進程
保存的用戶/組ID(saved set-xx-id)
- 配合set-user-ID 和 set-group-ID使用
- 其值爲複製的有效用戶/組ID
- 一些系統調用將標識S的進程的有效用戶ID在實際和保存ID間切換
文件系統用戶/組ID(file-system xx id)
- linux中對於文件的系統操做的權限是由文件系統ID(結合輔助組ID)決定的
- 通常來講文件系統ID等於有效用戶ID,不管是系統調用仍是設置了
set-user-ID
位,文件系統ID都會變成同一值,只有特殊的setfsuid()
,setfsgid()
纔會使不一致輔助組ID
#include<unistd.h>
uid_t getuid(void);
uid_t geteuid(void);
gid_t getgid(void);
gid_t getegid(void);
// 修改有效xxID 調用 ,均返回0:success, -1:fail
int setuid(uid_t uid);
int setgid(gid_t gid);
int seteuid(uid_t uid);
int setegid(gid_t gid);
複製代碼
- 非特權進程調用setuid
- 僅能修改有效用戶ID,
- 且僅能修改成實際的用戶ID和保存用戶ID
- setuid等效於seteuid
- 特權進程調用以一個非0參數x調用setuid,
- 用戶的3個id均會變爲x,且再也不是特權進程,不可逆
- 調用seteuid只改變euid,能夠以非特權的規則恢復
#include<unistd.h>
// uid, euid爲-1是不修改
int setreuid(uid_t ruid, uid_t euid);
int setregid(gid_t rgid, gid_t egid);
複製代碼
- 非特權進程可
- 將ruid 設爲 當前ruid, euid
- 將euid設爲 當前ruid, euid, suid
- 特權進程可
- 將ruid設爲任意值
- 將euid設爲任意值
- 知足如下之一suid會設爲euid:
- ruid不爲-1
- euid值不等於原ruid值
- 注意調用順序,修改了uid以後gid可能沒法修改
相似略
- 真實時間
- 進程時間(進程建立後使用cpu的時間)
- 用戶CPU時間
- 系統CPU時間
//系統時區 連接到/usr/share/zoninfo的某文件
$ ll /etc/localtime
lrwxrwxrwx 1 root root 25 5月 2 22:36 /etc/localtime -> ../usr/share/zoneinfo/UTC
複製代碼
$ locale
LANG=en_US.UTF-8
LC_CTYPE=zh_CN.UTF-8
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=
複製代碼
//修改環境變量執行
$ LANG=de_DE ./show_time
複製代碼
軟件時鐘(jiffies), linux時間精度取決於jiffies 時鐘頻率100,250,1000Hz 對應jiffies(10,4,1ms)