第八章 进程控制

1. 进程标识符

  pid_t getpid(void);  //返回调用进程的进程ID

  pid_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函数

<span style="font-size:18px;">#include "apue.h"

int globvar = 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) {
		globvar ++;
		var ++;
	} else {
		sleep(2);
	}
	
	printf("pid = %ld, glob = %d, var = %d\n", (long)getpid(), globvar, var);
	exit(0);
}
/*****************
a write to stdout
before fork
pid = 40882, glob = 7, var = 89
pid = 40881, glob = 6, var = 88
*****************/
</span>


3. 函数vfork

  在子进程调用exec或exit之前,它会在父进程的空间中进行。它会保证子进程先进行,在它调用exec或exit之后,父进程才能被调度运行。


4. wait 和 waitpid

  如果所有子进程都还在运行,则阻塞;如果一个子进程已终止,正等待父进程获取终止状态,则取得该子进程的终止状态立即返回;如果它没有任何子进程,则立即出错返回。

  pid_t wait(int *statloc);  

  pid_t waitpid(pid_t pid, int *statloc, int options); //pid和options对应不同的意义(P193)

#include "apue.h"
#include <sys/wait.h>

void pr_exit(int status)
{
	if(WIFEXITED(status))
		printf("normal termination, exit status = %d\n", WEXITSTATUS(status));
	else if(WIFSIGNALED(status))
		printf("abnormal termination, exit status = %d%s\n", WTERMSIG(status),
#ifdef  WCOREDUMP
		WCOREDUMP(status) ? " (core file generated)" : "");
#else
		"");
#endif
	else if(WIFSTOPPED(status))
		printf("child stopped, signal number = %d\n", WSTOPSIG(status));
}

int main(void)
{
	pid_t pid;
	int status;

	if((pid = fork()) < 0)
		err_sys("fork error");
	else if(pid == 0)
		exit(7);

	if(wait(&status) != pid)
		err_sys("wait error");
	pr_exit(status);	

	if((pid = fork()) < 0)
		err_sys("fork error");
	else if(pid == 0)
		abort();
	
	if(wait(&status) != pid)
		err_sys("wait error");
	pr_exit(status);

	if((pid = fork()) < 0)
		err_sys("fork error");
	else if(pid == 0)
		status /= 0;
	
	if(wait(&status) != pid)
		err_sys("wait error");
	pr_exit(status);
}
/**************************************
rmal termination, exit status = 7
abnormal termination, exit status = 6
abnormal termination, exit status = 8
**************************************/

  int waitid(idtype_t id, id_t id, siginfo_t, *infop, int options);  

  pid_t wait3(int *statloc, int options, struct rusage * rusage);

  pid_t wait4(pid_t pid, int statloc, int options, struct rusage *rusage); //rusage里面含有终止进程及其所有子进程使用的资源概况


5. 竞争条件

#include "apue.h"

void charatatime(char *);

int main()
{
	pid_t pid;

	TELL_WAIT();
	
	if((pid = fork()) < 0)
		err_sys("fork error");
	else if(pid == 0){
		charatatime("output from child\n");
		TELL_PARENT(getppid());
	}
	else{
		WAIT_CHILD();
		charatatime("output from parent\n");
	}
	exit(0);
}

void charatatime(char *ptr)
{
	char *str;
	int c;

	setbuf(stdout, NULL);
	for(str = ptr; (c = *str) != 0; str ++)
		putc(c, stdout);
}
/********************
utput from child
output from parent
********************/

6. 函数exec(? P199)


7. 更改用户ID和更改组ID,解释器文件(P204-210)


8. system函数

#include "apue.h"

int main()
{
	int status;
	
	if((status = system("date")) < 0)
		err_sys("system() error");
	
	pr_exit(status);
	

	if((status = system("nosuchcommand")) < 0)
		err_sys("system() error");
	
	pr_exit(status);

	if((status = system("who; exit 44")) < 0)
		err_sys("system() error");
	
	pr_exit(status);
}
/******************************************
Fri Jul  8 00:41:33 PDT 2016
normal termination, exit status = 0
sh: nosuchcommand: command not found
normal termination, exit status = 127
lll      :0           2016-07-07 23:19 (:0)
lll      pts/13       2016-07-07 23:19 (:0)
normal termination, exit status = 44
******************************************/

8. 进程会计 (记录的顺序对应于进程终止的顺序)


9. 进程调度

  int nice(int incr);  

  int getpriority(int which, id_t who); 

  //which 的参数有:PRIO_PROCESS(进程),PRIO_PGRP(进程组),PRIO_USER(用户ID)

  int setpriority(int which, id_t who, int value);

#include "apue.h"
#include <errno.h>
#include <sys/time.h>

#if defined(MACOS)
#include <sys/syslimits.h>
#elif defined(SOLARIS)
#include <limits.h>
#elif defined(BSD)
#include <sys/param/h>
#endif

unsigned long long count;
struct timeval end;

void checktime(char *str)
{
	struct timeval tv;
	
	gettimeofday(&tv, NULL);
	if(tv.tv_sec >= end.tv_sec && tv.tv_usec >= end.tv_usec){
		printf("%s count = %lld\n", str, count);
		exit(0);
	}
}

int main(int argc, char *argv[])
{
	pid_t pid;
	char *s;
	int nzero, ret;
	int adj = 0;

	setbuf(stdout, NULL);
#if defined(NZERO)
	nzero = NZERO;
#elif defined(_SC_NZERO)
	nzero = sysconf(_SC_NZERO);
#else
#error NZERO undefined
#endif
	printf("NZERO = %d\n", nzero);
	if(argc == 2)
		adj = strtol(argv[1], NULL, 10);
	gettimeofday(&end, NULL);
	end.tv_sec += 10;
	
	if((pid = fork()) < 0){
		err_sys("fork error");
	} else if(pid == 0) {
		s = "child";
		printf("current nice value in child is %d, adjusting by %d\n", nice(0)+nzero, adj);
		errno = 0;
		if((ret = nice(adj)) == -1 && errno != 0)
			err_sys("child set scheduling priority");
		printf("now child nice value is %d\n", nice(0) + nzero);
 	} else{
		s = "parent";
		printf("current nice in parent is %d\n", nice(0)+nzero);
	}
	for(;;){
		if(++ count == 0)
			err_quit("%s counter wrap", s);
		checktime(s);
	}
}
/************************************************
<< ./a.out
NZERO = 20
current nice in parent is 20
current nice value in child is 20, adjusting by 0
now child nice value is 20
parent count = 258526410
child count = 258645486
<< ./a.out 20
O = 20
current nice in parent is 20
current nice value in child is 20, adjusting by 20
now child nice value is 39
parent count = 507471598
child count = 7639840
************************************************/


10. 进程时间

  clock_t times(struct tms *buf);


  

    



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值