- 浏览: 61568 次
- 性别:
- 来自: 苏州
文章分类
最新评论
-
brxonline:
提示不能这样写234390216 写道234390216 写道 ...
mysql导出数据为excel -
234390216:
234390216 写道不行啊,错误
提示不能这样写
mysql导出数据为excel -
234390216:
不行啊,错误
mysql导出数据为excel
UNIX编程(8)-进程控制
- 博客分类:
- C
1.进程标识符
每个进程都有一个非负整数表示的唯一进程ID
#include <unistd.h> pid_t getpid(void);
|
Returns: process ID of calling process |
pid_t getppid(void);
|
Returns: parent process ID of calling process |
uid_t getuid(void);
|
Returns: real user ID of calling process |
uid_t geteuid(void);
|
Returns: effective user ID of calling process |
gid_t getgid(void);
|
Returns: real group ID of calling process |
gid_t getegid(void);
|
Returns: effective group ID of calling process |
2.fork函数
fork函数创建一个新的进程,调用一次返回两次,子进程的返回值是0,父进程的返回值是子进程的进程ID
#include <unistd.h> pid_t fork(void);
|
Returns: 0 in child, process ID of child in parent, 1 on error |
例:
#include "apue.h" int glob = 6; /* external variable in initialized data */ char buf[] = "a write to stdout\n"; int main(void) { int var; /* automatic variable on the stack */ pid_t pid; var = 88; if (write(STDOUT_FILENO, buf, sizeof(buf)-1) != sizeof(buf)-1) err_sys("write error"); printf("before fork\n"); /* we don't flush stdout */ if ((pid = fork()) < 0) { err_sys("fork error"); } else if (pid == 0) { /* child */ glob++; /* modify variables */ var++; } else { sleep(2); /* parent */ } printf("pid = %d, glob = %d, var = %d\n", getpid(), glob, var); exit(0); }
3.vfork函数
vfork函数和fork函数类似,但区别在于它并不将父进程的地址空间完全复制到子进程,因为子进程会立即调用exec或exit函数。另一个区别在于vfork保证子进程先运行。
例:
#include "apue.h" int glob = 6; /* external variable in initialized data */ int main(void) { int var; /* automatic variable on the stack */ pid_t pid; var = 88; printf("before vfork\n"); /* we don't flush stdio */ if ((pid = vfork()) < 0) { err_sys("vfork error"); } else if (pid == 0) { /* child */ glob++; /* modify parent's variables */ var++; _exit(0); /* child terminates */ } /* * Parent continues here. */ printf("pid = %d, glob = %d, var = %d\n", getpid(), glob, var); exit(0); }
4.exit函数
5. wait和 waitpid函数
#include <sys/wait.h> pid_t wait(int *statloc); pid_t waitpid(pid_t pid, int *statloc, int options);
|
Both return: process ID if OK, 0 (see later), or 1 on error |
两函数的区别:在一个子进程终止前wait使其调用者阻塞,而waitpid有一个选项,可使调用者不阻塞
例:
#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, signal number = %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)); }
#include "apue.h" #include <sys/wait.h> int main(void) { pid_t pid; int status; if ((pid = fork()) < 0) err_sys("fork error"); else if (pid == 0) /* child */ exit(7); if (wait(&status) != pid) /* wait for child */ err_sys("wait error"); pr_exit(status); /* and print its status */ if ((pid = fork()) < 0) err_sys("fork error"); else if (pid == 0) /* child */ abort(); /* generates SIGABRT */ if (wait(&status) != pid) /* wait for child */ err_sys("wait error"); pr_exit(status); /* and print its status */ if ((pid = fork()) < 0) err_sys("fork error"); else if (pid == 0) /* child */ status /= 0; /* divide by 0 generates SIGFPE */ if (wait(&status) != pid) /* wait for child */ err_sys("wait error"); pr_exit(status); /* and print its status */ exit(0); }
6.waitid函数
#include <sys/wait.h> int waitid(idtype_t idtype, id_t id, siginfo_t *infop, int options);
7.wait3和wait4函数
#include <sys/types.h> #include <sys/wait.h> #include <sys/time.h> #include <sys/resource.h> pid_t wait3(int *statloc, int options, struct rusage *rusage); pid_t wait4(pid_t pid, int *statloc, int options, struct rusage *rusage);
8.竞争条件
当多个进程都企图对共享数据进行某种处理,而最后的结果又取决于进程运行的顺序时,则我们认为发生了竞争条件
例:避免竞争
#include "apue.h"
static void charatatime(char *);
int
main(void)
{
pid_t pid;
TELL_WAIT();
if ((pid = fork()) < 0) {
err_sys("fork error");
} else if (pid == 0) {
WAIT_PARENT(); /* parent goes first */
charatatime("output from child\n");
} else {
charatatime("output from parent\n");
TELL_CHILD(pid);
}
exit(0);
}
static void
charatatime(char *str)
{
char *ptr;
int c;
setbuf(stdout, NULL); /* set unbuffered */
for (ptr = str; (c = *ptr++) != 0; )
putc(c, stdout);
}
9.exec函数
8.10. exec FunctionsWe mentioned in Section 8.3 that one use of the fork function is to create a new process (the child) that then causes another program to be executed by calling one of the exec functions. When a process calls one of the exec functions, that process is completely replaced by the new program, and the new program starts executing at its main function. The process ID does not change across an exec, because a new process is not created; exec merely replaces the current processits text, data, heap, and stack segmentswith a brand new program from disk. There are six different exec functions, but we'll often simply refer to "the exec function," which means that we could use any of the six functions. These six functions round out the UNIX System process control primitives. With fork, we can create new processes; and with the exec functions, we can initiate new programs. The exit function and the wait functions handle termination and waiting for termination. These are the only process control primitives we need. We'll use these primitives in later sections to build additional functions, such as popen and system.
|
例:
#include "apue.h" #include <sys/wait.h> char *env_init[] = { "USER=unknown", "PATH=/tmp", NULL }; int main(void) { pid_t pid; if ((pid = fork()) < 0) { err_sys("fork error"); } else if (pid == 0) { /* specify pathname, specify environment */ if (execle("/home/sar/bin/echoall", "echoall", "myarg1", "MY ARG2", (char *)0, env_init) < 0) err_sys("execle error"); } if (waitpid(pid, NULL, 0) < 0) err_sys("wait error"); if ((pid = fork()) < 0) { err_sys("fork error"); } else if (pid == 0) { /* specify filename, inherit environment */ if (execlp("echoall", "echoall", "only 1 arg", (char *)0) < 0) err_sys("execlp error"); } exit(0); }
#include "apue.h" int main(int argc, char *argv[]) { int i; char **ptr; extern char **environ; for (i = 0; i < argc; i++) /* echo all command-line args */ printf("argv[%d]: %s\n", i, argv[i]); for (ptr = environ; *ptr != 0; ptr++) /* and all env strings */ printf("%s\n", *ptr); exit(0); }
10.更改用户ID 和组ID
#include <unistd.h> int setuid(uid_t uid); int setgid(gid_t gid);
|
Both return: 0 if OK, 1 on error |
交换实际用户ID和有效用户ID
#include <unistd.h> int setreuid(uid_t ruid, uid_t euid); int setregid(gid_t rgid, gid_t egid);
|
Both return: 0 if OK, 1 on error |
只更改有效用户ID和有效组ID
#include <unistd.h> int seteuid(uid_t uid); int setegid(gid_t gid);
|
Both return: 0 if OK, 1 on error |
11.解释器文件
UNIX支持解释器文件,文件的格式如下
#! pathname [ optional-argument ]
12.system函数
#include <stdlib.h>
int system(const char *cmdstring);
|
Returns: (see below) |
返回类型说明:
如果fork失败,或者waitpid返回除EINTR之外的出错,则system返回-1,而且errno中设置了错误类型值
如果exec失败,则其返回值如同shell执行了exit(127)一样
否则所有三个函数(fork,exec,waitpid)都执行成功,并且system的返回值是shell的终止状态,其格式已在waitpid中说明
#include "apue.h" #include <sys/wait.h> int main(void) { 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); exit(0); }
13.进程会计
需先调用accton命令启动会计事务处理
acct结构体说明:
struct acct
{
char ac_flag; /* flag (see Figure 8.26) */
char ac_stat; /* termination status (signal & core flag only) */
/* (Solaris only) */
uid_t ac_uid; /* real user ID */
gid_t ac_gid; /* real group ID */
dev_t ac_tty; /* controlling terminal */
time_t ac_btime; /* starting calendar time */
comp_t ac_utime; /* user CPU time (clock ticks) */
comp_t ac_stime; /* system CPU time (clock ticks) */
comp_t ac_etime; /* elapsed time (clock ticks) */
comp_t ac_mem; /* average memory usage */
comp_t ac_io; /* bytes transferred (by read and write) */
/* "blocks" on BSD systems */
comp_t ac_rw; /* blocks read or written */
/* (not present on BSD systems) */
char ac_comm[8]; /* command name: [8] for Solaris, */
/* [10] for Mac OS X, [16] for FreeBSD, and */
/* [17] for Linux */
};
例:
产生进程会计数据
#include "apue.h" int main(void) { pid_t pid; if ((pid = fork()) < 0) err_sys("fork error"); else if (pid != 0) { /* parent */ sleep(2); exit(2); /* terminate with exit status 2 */ } /* first child */ if ((pid = fork()) < 0) err_sys("fork error"); else if (pid != 0) { sleep(4); abort(); /* terminate with core dump */ } /* second child */ if ((pid = fork()) < 0) err_sys("fork error"); else if (pid != 0) { execl("/bin/dd", "dd", "if=/etc/termcap", "of=/dev/null", NULL); exit(7); /* shouldn't get here */ } /* third child */ if ((pid = fork()) < 0) err_sys("fork error"); else if (pid != 0) { sleep(8); exit(0); /* normal exit */ } /* fourth child */ sleep(6); kill(getpid(), SIGKILL); /* terminate w/signal, no core dump */ exit(6); /* shouldn't get here */ }
查看进程会计数据
#include "apue.h" #include <sys/acct.h> #ifdef HAS_SA_STAT #define FMT "%-*.*s e = %6ld, chars = %7ld, stat = %3u: %c %c %c %c\n" #else #define FMT "%-*.*s e = %6ld, chars = %7ld, %c %c %c %c\n" #endif #ifndef HAS_ACORE #define ACORE 0 #endif #ifndef HAS_AXSIG #define AXSIG 0 #endif static unsigned long compt2ulong(comp_t comptime) /* convert comp_t to unsigned long */ { unsigned long val; int exp; val = comptime & 0x1fff; /* 13-bit fraction */ exp = (comptime >> 13) & 7; /* 3-bit exponent (0-7) */ while (exp-- > 0) val *= 8; return(val); } int main(int argc, char *argv[]) { struct acct acdata; FILE *fp; if (argc != 2) err_quit("usage: pracct filename"); if ((fp = fopen(argv[1], "r")) == NULL) err_sys("can't open %s", argv[1]); while (fread(&acdata, sizeof(acdata), 1, fp) == 1) { printf(FMT, (int)sizeof(acdata.ac_comm), (int)sizeof(acdata.ac_comm), acdata.ac_comm, compt2ulong(acdata.ac_etime), compt2ulong(acdata.ac_io), #ifdef HAS_SA_STAT (unsigned char) acdata.ac_stat, #endif acdata.ac_flag & ACORE ? 'D' : ' ', acdata.ac_flag & AXSIG ? 'X' : ' ', acdata.ac_flag & AFORK ? 'F' : ' ', acdata.ac_flag & ASU ? 'S' : ' '); } if (ferror(fp)) err_sys("read error"); exit(0); }
14.用户标识
#include <unistd.h> char *getlogin(void);
|
Returns: pointer to string giving login name if OK, NULL on error |
15.进程时间
#include <sys/times.h>
clock_t times(struct tms *buf);
|
Returns: elapsed wall clock time in clock ticks if OK, 1 on error |
tms结构体说明:
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]); /* once for each command-line arg */ exit(0); } static void do_cmd(char *cmd) /* execute and time the "cmd" */ { struct tms tmsstart, tmsend; clock_t start, end; int status; printf("\ncommand: %s\n", cmd); if ((start = times(&tmsstart)) == -1) /* starting values */ err_sys("times error"); if ((status = system(cmd)) < 0) /* execute command */ err_sys("system() error"); if ((end = times(&tmsend)) == -1) /* ending values */ 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) /* fetch clock ticks per second first time */ 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); }
发表评论
-
UNIX网络编程(1)-简介
2011-10-06 17:31 7541.bzero函数 bzero 等同于memset(void ... -
UNIX编程(15)-进程间通信
2011-08-07 12:09 1084. 管道 #include <un ... -
UNIX编程(14)-高级IO
2011-08-03 21:36 13771.非阻塞IO 对于一个给定的描述符有两种方法对其指定非阻塞 ... -
UNIX编程(13)-守护进程
2011-08-02 21:59 9241.守护进程的编程规则 1)用umask将文件模式创建屏蔽字 ... -
UNIX编程(12)-线程控制
2011-07-27 15:26 9111.线程限制 某些系统有线程的限制,可以通过sysconf函 ... -
UNIX编程(11)-线程
2011-07-27 14:34 9471.线程标识 每个线程都有一个线程ID,线程ID只在它所属的 ... -
UNIX编程(10)-信号
2011-07-20 21:18 9721.signal函数 #include ... -
UNIX编程(9)-进程关系
2011-07-12 14:41 11021.终端登录 2.网络登录 3.进程组 ... -
UNIX编程(7)-进程环境
2011-07-01 15:07 8631.main 函数 c程序总是从main函数开始执行,当内核 ... -
UNIX编程(6)-系统数据文件和信息
2011-06-28 16:35 11681.口令文件 口令文件存储在/etc/passwd中,是一个A ... -
UNIX编程(5)-标准IO库
2011-06-27 16:55 9161.流的定向 freopen函数清 ... -
UNIX编程(4)-文件和目录
2011-06-23 16:56 12431.stat,fstat,lstat函数 #include & ... -
UNIX编程(3)-文件IO
2011-06-21 17:45 14091.open函数 #include <fcntl.h&g ... -
UNIX编程(2)-UNIX标准化
2011-06-15 11:41 6751.ISO c 2.IEEE POSIX 3.Single U ... -
UNIX编程(1)-基础知识
2011-06-15 10:54 8061.登陆名 登陆名放在/etc ...
相关推荐
UNIX网络编程-第2卷-进程间通讯 UNIX网络编程-第2卷-进程间通讯
linux环境高级编程3-unix进程环境、进程控制和进程关系.ppt
UNIX网络编程----进程间通信----卷2【第二版】源码
unix实验关于进程通信的源码。。。。C编程实现无名管道通信和IPC通信
UNIX环境高级编程-13-精灵进程
本文为摘录,主要是在UNIX系统上的编程实践经验总结而成, 对UNIX程序员初学者来说是一个小小的经验, 仅供参考; 对UNIX老手来说则不值一哂, 请各位多多指 教.
本书全面深入地讲述了各种进程间通信(IPC)形式,它们是几乎所有复杂精致的UNIX程序的性能之关键。从网络编程角度看,理解IPC也是理解如何开发不同主机间网络应用程序的必要条件。本书从对Posix IPC和System V IPC...
卷2:进程间通信(第2版)》是一部UNIX网络编程的经典之作!进程间通信(IPC)几乎是所有Unix程序性能的关键,理解IPC也是理解如何开发不同主机间网络应用程序的必要条件。《UNIX网络编程.卷2:进程间通信(第2版)》从对...
UNIX网络编程第2卷-进程间通讯.pdf
笔记_UNIX环境网络编程卷二进程间通信_中文第二版
Unix网络编程第二卷 - 进程间通信.rar
UNIX环境高级编程一套电子书! 一共23部分19章。最后4部分为:函数原型、其它源码、习题答案、参考资料 如果您对某章节感兴趣,则下载非常方便! 如果此资源有侵权,请通知我,我会及时撤销下载!
UNIX网络编程第二卷-进程间通信-源代码 不同平台可能会遇到一些小问题 毕竟这些源代码有些年头了 关于我在fedora 11环境下编译出现的问题及解决办法见: ...
本书全面介绍了UNIX系统的程序设计界面—... 本书内容丰富权威,概念清晰精辟,一直以来被誉为UNIX编程的“圣经”,对于所有UNIX程序员—无论是初学者还是专家级人士—都是一本无价的参考书籍。 压缩包中是源代码。
当进程执行完毕或者自己主动挂起后,操作系统就会重新计算一 次所有进程的总优先级,然后再挑一个优先级最高的把 CPU 控制权交给他。 我们用分蛋糕的场景来描述这两种算法。假设有源源不断的蛋糕(源源不断的时间)...
UNIX网络编程 第2卷 进程间通信 把应用程序设计成一组彼此通信的小片断
UNIX环境高级编程一套电子书! 一共23部分19章。最后4部分为:函数原型、其它源码、习题答案、参考资料 如果您对某章节感兴趣,则下载非常方便! 如果此资源有侵权,请通知我,我会及时撤销下载!
两本经典书代码,希望对大家有用。 unix环境高级编程 unix网络编程.进程间通信
UNIX网络编程 卷2 进程间通信(第2版)
UNIX网络编程第二卷 进程间通信