(一)
当多个进程企图对共享数据进行某种处理,而最后的结果又取决于进程运行的顺序时,就认为它们发生了竞争关系。避免竞争的条件,给出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个只是库函数,它们最终都要调用该系统调用。