Linux中进程的深入学习

进程


进程是在系统中能够独立运行的活动实体。由(机器指令)PCB,数据,堆栈组成。
引入进程的目的:为了使多个程序能够并发的执行,提高系统的吞吐量。

进程调度方式:
<1>非抢占式方式
<2>抢占式方式:优先权原则,短作业优先,时间片原则。

进程调度算法:
<1>先来先服务调度算法
<2>短作业优先调度算法
<3>高优先权调度算法
<4>基于时间片轮转调度算法

Linux系统中的进程类型
<1>交互进程:由shell控制和运行,可以在前台或后台运行。
<2>批处理进程:该进程被提交到队列中顺序执行。
<3>守护进程:该进程在后台运行。

Linux运行状态
<1>运行态
<2>等待态
<3>停止态
<4>死亡态

调度进程
ps    查看系统中的进程 aux-->显示该进程所有信息 elf  ajx
top   动态显示系统进程  q结束
kill  结束进程
bg    将挂起的进程放到后台执行
fg    把后台的进程放到前台运行

===================================================================
进程创建:fork()
头文件:#include <sys/types.h>
 #include <unistd.h>
函数体:pid_t fork(void);
返回值:0--->子进程  子进程的PID---->父进程   -1---->出错

例:
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <errno.h>

extern int errno;

int main()
{
 int a=10;
 pid_t pid;
 if(0 > (pid = fork()))
 {
  fprintf(stderr,"error :%s",strerror(errno));
  return -1;
 }
 else if(0 == pid)
 {
  a=100;
  printf("this is child %d\n",getpid());
  printf("this is parent %d\n",getppid());
  printf("a===%d\n",a);
 }
 else
 {
  sleep(2);
  printf("this is my child PID %d\n",pid);
  printf("this is myself PID %d\n",getpid());
  printf("a---%d\n",a);
 }
 printf("==================\n");
 return 0;
}

【注意】:
<1>父进程先exit(),子进程成为孤儿进程由init回收。
<2>子进程先exit(),变为等待父进程回收资源,如果父进程不退出,子进程变成僵尸进程。

exec()函数族
exec()用途:如果某个进程想同时执行另一个程序,他就可以调用fork()函数创建子进程,然后在子进程中调用任何一个exec()函数,就可以让子进程执行新的程序。

头文件: #include <unistd.h>
函数体: int execl(const char *path,const char *arg,...);
                int execv(const char *path,char *argv[]);
                int execle(const char *path,char *arg,...char *envp[]);
                int ececve(const char *path,char *argv[],chr *envp[]);
                int execlp(cosnt char *file,char *arg);
                int execvp(const char *file,char *argv[]);

例子:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
extern int errno;

int main()
{
 pid_t pid;

 if(0 > (pid = fork()))
 {
  fprintf(stderr,"error :%s\n",strerror(errno));
  return -1;
 }
 else if(0 == pid)
 {
  pid_t psd;
  if(0 > (psd = fork()))
  {
   fprintf(stderr,"error :%s\n",strerror(errno));
   return -1;
  }
  else if(0 == psd)
  {
   char *argv[]={"cat","1.txt",NULL};
   execv("/bin/cat",argv);
  }
  else
  {
   execl("/bin/ls","1","-la","/program/",NULL);
  }
 }
 else
 {
  int status;
  wait(&status);
  execl("/bin/cat","1","1.txt",NULL);
 }
 return 0;
}

 : int execve(const char *path,char *const argv[],char *const envp[]);
例子:

s1.c文件
  1 #include <stdio.h>
  2 #include <unistd.h>
  3 #include <stdlib.h>
  4 #include <string.h>
  5
  6 int main(int argc, char *argv[])
  7 {
  8         char *buf = getenv("PATH1");
  9         printf("envirment: %s\n",buf);
 10
 11         return 0;
 12 }

s2.c文件
  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <unistd.h>
  4 #include <sys/types.h>
  5
  6 int main()
  7 {
  8         char *argv1[]={"./s1","1",NULL};
  9         char *argv2[]={"PATH1=/usr/lib",NULL};
 10
 11         execve("s1",argv1,argv2);
 12         printf("=========\n");
 13         return 0;
 14 }
   
编译:
gcc -o s1 s1.c
gcc -o s2 s2.c
./s2

========================================================================
exit()与_exit()

头文件:exit  :#include <stdlib.h>
 _exit :#include <unistd.h>

函数体: exit  :void exit(int status);  //status 是参数值 0表示正常结束
 _exit :void _exit(int status);

区别:
exit()  :使用exit()系统会检查文件的打开情况,把文件缓冲区的内容写回到文件。
_exit() :使用_exit()直接会使进程终止运行,清除其使用的内存空间,并销毁内核中的各种数据结构。

例子:
<1>#include <stdio.h>
#include <stdlib.h>

int main()
{
 printf("-----sunxu-----");
 printf("-----hello-----");
 exit(0);
 return 0;   输出:-----sunxu----------hello-----
}

<2>#include <stdio.h>
#include <unistd.h>

int main()
{
 printf("-----sunxu-----\n");
 printf("-----hello-----");
 _exit(0);
 return 0;   输出:-----sunxu-----
}

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()   :使用该函数使进程阻塞,直到任意一个子进程结束或者是该进程收到一个信号为止。成功返回子进程的进程号,失败-1。status保存子进程退出时的状态。
waitpid():可以指定的等待某个子进程的结束以及等待的方式。(阻塞与非阻塞)。返回子进程的进程号。

例子:
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <errno.h>
#include <sys/wait.h>
#include <stdlib.h>

extern int errno;

int main()
{
 pid_t pid;
 if(0 > (pid = fork()))
 {
  fprintf(stderr,"error :%s",strerror(errno));
  return -1;
 }
 else if(0 == pid)
 {
  printf("this is child %d\n",getpid());
  printf("this is parent %d\n",getppid());
  sleep(3);
  exit(88);
 }
 else
 {
  sleep(4);
  int status;

  pid_t pd;
  //pd=wait(&status);
  pd=waitpid(pid,&status,0);

  printf("pd===%d\n",pd);
  printf("status++%d\n",status);
  printf("this is my child PID %d\n",pid);
  printf("this is myself PID %d\n",getpid());
 }
 return 0;
}         

atexit()函数

用途     :设置程序正常结束前调用的函数,相当于入栈与出栈。
头文件   :#include <stdlib.h>
函数体   : int atexit(void (*function)(void));

例子:
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>

void fun1(void)
{
 printf("fun1\n");
}

void fun2(void)
{
 printf("fun2\n");
}

int main(int argc, char *argv[])
{
 atexit(fun1);
 atexit(fun2);
 exit(0);
}

=========================================================
Linux守护进程
守护进程是Liunx中的后台服务进程,在系统启动时开始运行,在系统关闭时终止。
Linux中从终端开始运行的进程都会依附于这个终端,这个终端称为这些进程的控制终端。当控制终端被关闭时,相应的进程都会被自动关闭。但守护进程不会依附于这个终端。

Linux守护进程编写步骤:
1.创建子进程,父进程退出。
2.在子进程中创建新会话。
3.改变当前目录                  #通常是让"/" 或"/tmp"作为守护进程的当前工作目录。
4.从设文件权限掩码。
5.关闭文件描述符。

流程: 开始--->fork() exit() --->setsid() ---->chdir("/")--->umask(0)----close()--->结束

例如:

创建一个守护进程init.c文件

#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>

extern int errno;

void init_daemon(void)
{
 int pid;
 int i;

 if(pid = fork())
 {
  exit(0);
 }
 else if(0 > pid)
 {
  fprintf(stderr,"%d:---%s\n",__LINE__,strerror(errno));
  exit(-1);
 }

 setsid();   //第一个子进程成为新的会话组长和进程组长,并与控制终端分离。


 for(i=0 ; i < getdtablesize();i++)
  close(i);
 chdir("/home");
 umask(0);

 return ;
}

创建一个main.c测试文件

#include <stdio.h>
#include <time.h>

void init_daemon(void);

int main()
{
 FILE *fp;
 time_t t;

 init_daemon();

 while(1)
 {
  sleep(2);
  if((fp = fopen("test.log","a"))!=NULL)
  {
   t = time(0);
   fprintf(fp,"I am here at %sn",asctime(localtime(&t)));
   fclose(fp);
  }

 }
 return 0;
}

编译:<1> gcc -o fun init.c main.c
      <2> ./fun
查看:tail -f /home/test.log

 

尊重作者,请转明来处:追Dream梦http://blog.csdn.net/pzhsunxu/article/details/7798319

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值