当前位置: 代码迷 >> 综合 >> Linux下C进程管理(fork,wait,exec)
  详细解决方案

Linux下C进程管理(fork,wait,exec)

热度:27   发布时间:2023-12-14 09:40:42.0

在我们编程中用的最多是函数,也就是如何函数调用。那我们如何调用函数呢?
一:我们必须要知道函数的功能是什么?
二:再看这个函数需要哪些参数?
三:最后看返回值是什么?
当我们面对一个函数时,既不知道函数的功能也不参数以及返回值时,我们该如何下手呢?
必须得动手查询呗,可以使用函数手册,终端,以及书本资料等、
现在就用fork,wait,exec来举例说明:
fork
功能:创建一个新的进程

一个现存进程调用fork函数是linux内核创建一个新进程的唯一方法(交换进程、init进程和页精灵进程并不是这样,这些进程是由内核作为自举过程的一部分以特殊方式创建的)。

参数pid_t fork(void);
返回值:一个是子进程返回0,第二个是父进程的返回值大于0.错误返回-1.
头文件:include<unistd.h>
wait
功能:等待进程
参数
pid_t wait(int*status);返回值:调用成功,返回子进程的PID,发生错误返回-1。错误原因放在全局变量errno中
头文件

#include<sys/types.h>

#include<sys/wait.h>
waitpid
函数说明:

在一个子进程结束之前,wait使其调用者阻塞,waitpid使用WNOHANG参数以非阻塞方式等待子进程,waitpid可以指定所需要等待的子进程。

         pid == - 1 等待任一子进程。于是在这一功能方面waitpid与wait等效。

         pid > 0 等待其进程 I D 与 p i d 相等的子进程。

         pid == 0 等待其组 I D 等于调用进程的组 I D 的任一子进程。

         pid < - 1 等待其组 I D 等于 p i d 的绝对值的任一子进程。
函数原型:

pid_twaitpid(pid_t pid, int *status, int options);

返回值:
执行成功,返回PID为状态改变的子进程。如果指定了WNOHANG,pid参数所代表的子进程没有发生状态变化,0会被返回。执行失败返回-1。错误原因存放在errno中。
头文件:

#include<sys/types.h>

#include <sys/wait.h>

exec

功能:在用f o r k函数创建子进程后,子进程往往要调用一个e x e c函数以执行另一个程序

当进程调用一种e x e c函数时,该进程完全由新程序代换,而新程序则从其m a i n函数开始执行。因为调用e x e c并不创建新进程,所以前后的进程I D并未改变。e x e c只是用另一个新程序替换了当前进程的正文、数据、堆和栈段。
函数原型

int execl( constchar *path, const char *arg, ...);

int execlp(const char *file, const char *arg, ...);

int execle(  const char  *path, const char *arg ,..., char * const envp[]);

int execve(constchar * pathname char *const a rgv [], char *const envp []);

int execv( constchar *path, char *const argv[]);

int execvp(const char *file, char *const argv[]);

巧记

E:指可以传递环境变量表

L:单独的参数传递,最后要有一个NULL

V:传一个指针数组名

P:按照环境变量来查找



范例:

char*ps_argv[]={“ps”,”ax”, NULL};

char*ps_envp[]={“PATH=/bin:/usr/bin”,”TERM=console”, NULL}

execl(“/bin/ps”,“ps”, “ax”, NULL);

execv(“/bin/ps”,ps_argv);

execle(“/bin/ps”,“ps”, “ax”, NULL, ps_envp);

execve(“/bin/ps”,ps_argv, ps_envp);

execlp(“ps”,“ps”, “ax”, NULL);

execvp(“ps”,ps_argv);

execl(“/bin/ps”,“ps”, “ax”, NULL);

execlp(“ps”,“ps”, “ax”, NULL);

execv(“/bin/ps”,ps_argv);

execvp(“ps”,ps_argv);


返回值:成功了没返回值,失败了返回-1.
头文件
#include<unistd.h>


代码如下:
#include<stdio.h>
#include<unistd.h>
#include<time.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<stdlib.h>
#include<string.h>
#define BUFSIZE 256
int main(void)
{
pid_t pid;
int i=0,j=0,m=0;
char buf[BUFSIZE],cmd[BUFSIZE];
char *argv[10]={NULL};
char *gete=getenv("HOSTNAME");
printf("%s",gete);
while(1)
{
while(gete[m]!='.')
        {
                buf[m++]=gete[m];
        }  
        printf("%s@%s%s",getenv("USER"),buf,getenv("PWD"));
        fgets(cmd,BUFSIZE,stdin);//stdin表示终端
*strchr(cmd, '\n') = ' ';//strchr查找字符串中第一个出现的指定字符
pid=fork();
if(pid==-1)
{
perror("error!\n");
//perror打印出错误原因信息字符串
exit(-1);
}
else if(pid==0)
{
while (i < BUFSIZE && cmd[i] != '\0')
{          if (cmd[i] != ' ')  {      argv[j++] = &cmd[i];
                     i = strchr(&cmd[i], ' ') - cmd; cmd[i] = '\0'; } i++;  }
//通过while循环来截取需要的字符,字符串是以'\0' 结束的。
            execvp(argv[0], argv);
perror("exec:");
             exit(0);
}
else
{
waitpid(pid,NULL,0);
}
}
return 0;
}
  相关解决方案