1. 進程標識符
#include <unistd.h>
pid_t getpid(void); //返回值:調用進程的進程ID
pit_t getppid(void); //返回值:調用進程的父進程ID
uid_t getuid(void); //返回值:調用進程的實際用戶ID
uid_t geteuid(void); //返回值:調用進程的有效用戶ID
gid_t getgid(void); //返回值:調用進程的實際組ID
gid_t getegid(void); //返回值:調用進程的有效組ID
2.fork函數
現有進程調用fork創建新進程
#include <unistd.h>
pid_t fork(void);
由fork創建的新進程爲child process。fork被調用一次,返回兩次。child返回值是0,father返回值是新進程的進程ID。
fork使father返回值爲child的進程ID的理由:一個進程有多個child,沒有一個函數使進程可以獲得其所有child的進程ID。
fork使child返回值0的理由:一個進程只有一個父進程,調用getppid可以獲得father的進程ID,而且進程ID 0 爲內核交換進程使用,child的ID不可能爲0。
child 和father進程繼續執行fork調用之後的指令
#include "apdu.h"
int glob=6;
char buf[]="a write to stdout\n";
int main(void)
{
int var;
pid_t pid;
var = 88;
if(write(STDOUT_FILENO, buf, sizeof(buf)-1)!=sizeof(buf)-1)
err_sys("write error");
printf("before fork\n");
if((pid=fork())<0){
err_sys("fork error");
}
else if(pid == 0){
glob++;
var++;
}
else{
sleep(2);
}
printf("pid=%d,glob=%d,var=%d\n",getpid(),glob,var);
exit(0);
}
wait 和 waitpid函數
- 如果其所有子進程都還在運行,則阻塞。
- 如果一個子進程已終止,正等待父進程獲取其終止狀態,則取得該子進程的終止狀態立即返回。
- 如果它沒有任何子進程,則立即出錯返回。
#include<sys/wait.h>
pid_t wait(int *statloc);
pid_t waitpid(pid_t pid, int *statloc, int options);
//return: 進程ID of OK, 0, -1 on error
區別:
- 在一個子進程終止前,wait使其調用者阻塞,而waitpid有一個選項,可使調用者不阻塞。
- waitpid並不等待在其調用之後的第一個終止子進程,它有若干個選項,可以控制它所等待的進程。
waitpid的參數pid
- pid==-1 等待任一子進程。
- pid>0 等待其進程ID與pid相等的子進程。
- pid==0 等待其組ID等於調用進程組ID的任一子進程。
- pid<- 1 等待其組ID等於pid絕對值的任一子進程。
options參數(沒看懂):
- WCONTINUED 若實現支持作業控制,那麼由pid指定的任一子進程在暫停後已經繼續,但其狀態尚未報告,則返回其狀態
- WNOHANG 若由pid指定的子進程並不是立即可用的,則waitpid不阻塞,此時其返回值爲0
- 若某實現支持作業控制,而由pid指定的任一子進程已處於暫停狀態,並且其狀態自暫停以來還未報告過,則返回其狀態。WIFSTOPPED宏確定返回值是否對應於一個暫停子進程
用戶標識
獲取登錄名
#include<unistd.h>
char *getlogin(void)
如果調用此函數的進程沒有連接到用戶登錄時所用的終端,則本函數會失敗。(守護進程)
進程調度
#include <unistd.h>
int nice(int incr);
//返回值:成功返回新的nice值NZERO;若出錯返回-1
進程時間
牆上時鐘時間(wall clock time),是進程運行的時間總量
#include<sys/times.h>
clock_t times(struct tms *buf);
//返回值:若成功則返回流逝的牆上時鐘時間(單位:時鐘滴答數)若出錯則返回-1
struct tms{
clock_t tms_utime; /*user CPU time*/
clock_t tms_stime; /*system CPU time*/
clock_t tms_cutime; /* user CPU time, terminated children*/
clock_t tms_cstime; /*system CPU time, terminated children*/
};
#include"apue.h"
#include<sys/times.h>
static void pr_times(clock_t, struct tms *,struct tms*);
static void do_cmd(char *);
int main(int argc, char *argv[])
{
int i;
setbuf(stdout, NULL);
for(i=1;i<argc;i++)
do_cmd(argv[i]);
exit(0);
}
static void do_cmd(char *cmd)
{
struct tms tmsstart, tmsend;
clock_t start, end;
int status;
printf("\ncommand:%s\n", cmd);
if((start = times(&tmsstart))==-1)
err_sys("times error");
if((status=system(cmd))<0)
err_sys("system() error");
if((end= times(&tmsend))==-1)
err_sys("times error");
pr_times(end-start,&tmsstart,&tmsend);
pr_exit(status);
}
static void pr_times(clock_t real, struct tms *tmsstart, struct tms *tmsend)
{
static long clktck = 0;
if(clktck == 0)
if((clktck = sysconf(_SC_CLK_TCK))<0)
err_sys("sysconf error");
printf(" real: %7.2f\n", real/(double) clktck);
printf(" user: %7.2f\n",
(tmsend->tms_utime - tmsstart->tms_utime)/(double)clktck);
printf(" sys: %7.2f\n",
(tmsend->tms_stime - tmsstart->tms_stime)/(double)clktck);
printf(" child user: %7.2f\n",
(tmsend->tms_cutime-tmsstart->tms_cutime)/(double)clktck);
printf(" child sys: %7.2f\n",
(tmsend->tms_cstime-tmsstart->tms_cstime)/(double)clktck);
}