kunyashaw博客主页 关注kunyashaw新博客 关于kunyashaw 转到底部

linux ——process

1、概念

进程是具有独立功能的程序关于某个数据集合的一次运行活动,是系统进行资源管理的基本单位。

(程序是存放在存储介质上的静态指令的集合,与进程最大的区别,程序是静态的,进程是动态的)

2、用途

进程是管理事务的基本单元:操作系统是通过进程去完成某个任务,管理事务,就好像,学校是通过班级管理事情,公司是通过部门去管理

3、特点

进程就运行的状态可分为三种状态,就绪态、运行态、阻塞态。

运行态<==>就绪态<---阻塞态<----运行态

4、用法

①创建进程

#include <unistd.h>

pid_t fork(void);

pid_t vfork(void);

fork与vfork的区别与共同点:

区别:

①fork创建的进程父、子进程运行顺序不确定,而vfork创建的进程保证子进程先运行,子进程结束(调用exit或exec)运行父进程再运行

②fork创建的子进程完全是父进程的一个复制品,它从父进程处继承了整个地址空间,而vfork在调用exec或exit之前,它在父进程的地址空间运行,在exec之后子进程会有自己的进程空间

③vork可以实现父子进程之间简单的同步

共同点:

都可以创建一个新进程

②进程的资源回收

#include <sys/types.h>

#include <sys/wait.h>

pid_t wait(int *status);

等待子进程改变状态,如果子进程终止了,此函数会回收子进程的资源。调用wait函数的进程会挂起,直到它的一个子进程退出或受到一个不能被忽视的信号时才被唤醒。

执行成功返回子进程的pid号,出错返回-1.

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

 

等待子进程改变状态,如果子进程终止了,此函数会回收子进程的资源。

pid>0 等待进程id等于pid的子进程;

pid=-1;等待任一子进程,此时waitpid和wait作用一样

pid<-1 等待指定进程组中的任何子进程,这个进程组的id等于pid的绝对值。

③进程的关闭

#include <stdlib.h>

void exit(int status);

exit函数:结束进程执行
#include <unistd.h>
void exit(int value)
参数:
    status:返回给父进程的参数(低8位有效)。
_exit函数:结束进程执行
#include <unistd.h>
void _exit(int value)
参数:
    status:返回给父进程的参数(低8位有效)。

exec函数族,是由六个exec函数组成的。
exec函数族提供了六种在进程中启动另一个程序的方法。
exec函数族可以根据指定的文件名或目录名找到可执行文件。
调用exec函数的进程并不创建新的进程,故调用exec前后,进程的进程号并不会改变,其执行的程序完全由新的程序替换,而新程序则从其main函数开始执行。

#include <unistd.h>
int execl(const char *pathname,           const char *arg0,…,NULL);
int execlp(const char *filename,              const char *arg0,…,NULL);
int execle(const char *pathname,           const char *arg0,…,NULL,              char *const envp[]);

int execv(const char *pathname,                 char *const argv[]);
int execvp(const char *filename,                              char *const argv[]);
int execve(const char *pathname,            char *const argv[],             char *const envp[]);

六个exec函数中只有execve是真正意义的系统调用(内核提供的接口),其它函数都是在此基础上经过封装的库函数。
l(list):
  参数地址列表,以空指针结尾。
参数地址列表
 char *arg0, char *arg1, ..., char *argn, NULL
v(vector):
  存有各参数地址的指针数组的地址。
  使用时先构造一个指针数组,指针数组存各参数的地址,然后将该指针数组地址作为函数的参数。

p(path)
  按PATH环境变量指定的目录搜索可执行文件。
  以p结尾的exec函数取文件名做为参数。当指定filename作为参数时,若filename中包含/,则将其视为路径名,并直接到指定的路径中执行程序。
e(environment):
  存有环境变量字符串地址的指针数组的地址。execle和execve改变的是exec启动的程序的环境变量(新的环境变量完全由environment指定),其他四个函数启动的程序则使用默认系统环境变量。

5、案例

 


#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <wait.h>

void shell(void)
{
 while(1)
 {
  char cmd_buf[200] = "";
  char *argv[20] = {NULL};
  int i = 0;
  
  getcwd(cmd_buf, sizeof(cmd_buf));//获取当前目录保存在字符数组当中。
  printf("[%s@ %s]$", getenv("USER"), 1+strrchr(cmd_buf, '/'));//打印提示符号。
  fgets(cmd_buf, sizeof(cmd_buf), stdin);//获取字符串
  cmd_buf[strlen(cmd_buf)-1] = '\0';   //把最后一位'\n'变成字符串结束标志'\0'
  
  if(cmd_buf[0] == '\0')
   continue;    //如果是输入回车的话,继续while循环
  
  argv[i] = cmd_buf;
  while((argv[i++]=strtok(argv[i]," "))!=NULL);   //字符串按空格切割  
  
  if(fork()==0)  //创建子进程  调用execvp运行外部命令。
  {
   printf("argv[0] = %s\n", argv[0]);
   execvp(argv[0],argv);  
   printf("command no found!\n");
   exit(1);
  }
  wait(NULL);  //父进程等待子进程结束。
 }
}

int main(int argc, char *argv[])
{
 shell();
 return 0;
}


 

posted @ 2013-06-08 18:25  kunyashaw  阅读(226)  评论(0编辑  收藏  举报
回到顶部