linux c 进程控制

来源:互联网 发布:js 文件下载 编辑:程序博客网 时间:2024/06/09 20:36


fork用于创建进程。

set follow-fork-mode child命令设置gdb在fork之后跟踪子进程(set follow-fork-mode parent则是跟踪父进程),然后用run命令。fork在子进程中返回0,子进程仍可以调用getpid函数得到自己的进程id,也可以调用getppid函数得到父进程的id。在父进程中用getpid可以得到自己的进程id,然而要想得到子进程的id,只有将fork的返回值记录下来。

原型:

#include <sys/types.h>#include <unistd.h>pid_t fork(void);


fork调用失败则返回-1

///////////////////////////////////////////////////////////////

Exec函数族

#include <unistd.h>int execl(const char *path, const char *arg, ...);int execlp(const char *file, const char *arg, ...);int execle(const char *path, const char *arg, ..., char *const envp[]);int execv(const char *path, char *const argv[]);int execvp(const char *file, char *const argv[]);int execve(const char *path, char *const argv[], char *const envp[]);


不带字母p(表示path)的exec函数第一个参数必须是程序的相对路径或绝对路径,例如"/bin/ls"或"./a.out",而不能是"ls"或"a.out"。对于带字母p的函数:

如果参数中包含/,则将其视为路径名。

否则视为不带路径的程序名,在PATH环境变量的目录列表中搜索这个程序。

带有字母l(表示list)的exec函数要求将新程序的每个命令行参数都当作一个参数传给它,命令行参数的个数是可变的,因此函数原型中有...,...中的最后一个可变参数应该是NULL,起sentinel的作用。对于带有字母v(表示vector)的函数,则应该先构造一个指向各参数的指针数组,然后将该数组的首地址当作参数传给它,数组中的最后一个指针也应该是NULL,就像main函数的argv参数或者环境变量表一样。

对于以e(表示environment)结尾的exec函数,可以把一份新的环境变量表传给它,其他exec函数仍使用当前的环境变量表执行新程序。

例程:

char *const ps_argv[] ={"ps", "-o", "pid,ppid,pgrp,session,tpgid,comm", NULL};char *const ps_envp[] ={"PATH=/bin:/usr/bin", "TERM=console", NULL};execl("/bin/ps", "ps", "-o", "pid,ppid,pgrp,session,tpgid,comm", NULL);execv("/bin/ps", ps_argv);execle("/bin/ps", "ps", "-o", "pid,ppid,pgrp,session,tpgid,comm", NULL, ps_envp);execve("/bin/ps", ps_argv, ps_envp);execlp("ps", "ps", "-o", "pid,ppid,pgrp,session,tpgid,comm", NULL);execvp("ps", ps_argv);


/////////////////////////////////////////////////////////////////////////////////////////

主要还是fork吧,exec用得不多!

这个进程的父进程可以调用wait或waitpid获取这些信息,然后彻底清除掉这个进程(避免僵尸进程产生)。

孤儿进程:父进程结束了子进程还没结束。

原型:

#include <sys/types.h>#include <sys/wait.h>pid_t wait(int *status);pid_t waitpid(pid_t pid, int *status, int options);


如果父进程的所有子进程都还在运行,调用wait将使父进程阻塞,而调用waitpid时如果在options参数中指定WNOHANG可以使父进程不阻塞而立即返回0。

wait等待第一个终止的子进程,而waitpid可以通过pid参数指定等待哪一个子进程。

 

进程间通信:

管道是一种最基本的IPC机制,由pipe函数创建:

#include <unistd.h>int pipe(int filedes[2]);


它有一个读端一个写端,然后通过filedes参数传出给用户程序两个文件描述符,filedes[0]指向管道的读端,filedes[1]指向管道的写端(很好记,就像0是标准输入1是标准输出一样)。所以管道在用户程序看起来就像一个打开的文件,通过read(filedes[0]);或者write(filedes[1]);向这个文件读写数据其实是在读写内核缓冲区。pipe函数调用成功返回0,调用失败返回-1。

Fork pipe综合练习代码:

#include <stdlib.h>#include <stdio.h>#include <unistd.h>#define MAXLINE 80int main(void){        int n;        int fd[2];        pid_t pid;        char line[MAXLINE];        if (pipe(fd) < 0) {     //管道                perror("pipe");                exit(1);        }        if ((pid = fork()) < 0) {                perror("fork");                exit(1);        }        if (pid > 0) {          /* parent 写数据 */                printf("this is parent pid=%d\n", getpid());                close(fd[0]);                printf("清输入数据:");                char arry[1024] = " ";                scanf("%s", arry);                write(fd[1], arry, sizeof(arry));                wait(NULL);        } else {                /* child 读数据 */                printf("this is child pid=%d\n", getpid());                close(fd[1]);                n = read(fd[0], line, MAXLINE);                write(STDOUT_FILENO, line, n);  //打印到屏幕        }        return 0;}


 //注:Linux下    indent -kr -i8 fork.c 命令可以自动把代码格式化成某种风格。(-kr选项表示K&R风格,-i8表示缩进8个空格的长度)

编译结果:

[huangbin@localhost shujia]$ ./a.out

this is child pid=26328

this is parent pid=26327

清输入数据:你好

你好

[huangbin@localhost shujia]$ ./a.out

this is child pid=26332

this is parent pid=26331

清输入数据:你好 大家好

你好

[huangbin@localhost shujia]$ ./a.out

this is parent pid=26333

清输入数据:this is child pid=26334

你好大家好

你好大家好

[huangbin@localhost shujia]$ 

管道的读端读到空格就停???没注意过以前。现在没网查不了。。。。

以为是write的原因,加上printf("%s\n",line);

结果:

[huangbin@localhost shujia]$ ./a.out

this is child pid=26350

this is parent pid=26349

清输入数据:hello world

hello

hello

[huangbin@localhost shujia]$ ./a.out

this is child pid=26352

this is parent pid=26351

清输入数据:hello,world!

hello,world!

hello,world!

一样的问题。以后解决!


解决办法:

  用fprintf(stdin,"%[^\n]",str);代替scanf("%s",str);

或者用gets(),也可以。因为scanf这个函数遇到空格就会断,后面的就没有再读进缓冲去了。

原创粉丝点击