(一)
当多个进程企图对共享数据进行某种处理,而最后的结果又取决于进程运行的顺序时,就认为它们发生了竞争关系。避免竞争的条件,给出apue上的一个代码吧:
#include "apue.h"
static void charatatime(char *);
int
main(void)
{
pid_t pid;
TELL_WAIT(); /*set things up for TELL_XXX & WAIT_XXX*/
if((pid == fork()) < 0){
err_sys("fork error");
}else if(pid == 0){
WAIT_PARENT(); /*tell parent wr're done*/
charatatime("output from child.\n");
}else{
charatatime("output from parent.\n");
TELL_CHILD(pid); /*tell child we're done*/
}
exit(0);
}
static void charatatime(char *str)
{
char *ptr;
int c;
setbuf(stdout, NULL);
for(ptr = str; (c = *ptr++) != 0;)
putc(c, stdout);
}
(二)
对基本的进程控制原语,前面提到用fork可以创建新进程,exit函数和两个wait函数处理终止和等待终止,用exec函数可以执行新的程序。
#include <unistd.h>
extern char **environ;
int execl(const char *path, const char *arg, ...);
int execv(const char *path, char *const argv[]);
int execle(const char *path, const char *arg, ..., char * const envp[]);
int execve(const char *path, const char *arg, ..., char * const envp[]);
int execvp(const char *file, char *const argv[]);
int execlp(const char *file, const char *arg, ...);
这些函数的区别有:
1、前4个去路径名作为参数,后两个取文件名作为参数。
2、与参数表的传递有关(l表示list,v表示vector)。
3、与向新程序传递环境表相关。以e结尾的两个函数可以传递一个指向环境字符串指针数组的指针。其他4个函数则使用调用进程中的environ变量为新程序复制现有环境。
这6个函数中只有execve是内核的系统调用。另外5个只是库函数,它们最终都要调用该系统调用。