教你10分钟学会linux进程

  1. 进程:
    进程是一个独立的可调度的活动,进程是一个抽象实体,当它执行某个事物时要分配和释放各种资源。它区别于程序,程序是静态的它是一些保存在磁盘上的指令的有序集合,而进程是程序执行的过程。

  2. 多任务:
    在同一时刻有多个任务运行,一个程序在运行时要独占cpu资源,而多任务的处理机制源于cpu的告诉运转。哪个进程先被执行是不确定的,取决于内核中的进程调度。

  3. 在linux下创建一个新的进程。
    fork()函数用于在已经存在的进程中创建一个子进程,这个字进程从父进程出继承了整个进程的空间。所以执行速度很慢,这就是引出线程的原因。

	#include <stdio.h>
	#include <stdlib.h>
	#include <unistd.h>
	
	int main()
	{
	
	pid_t pid;
	pid = fork();
	if(pid < 0)
	{
		printf("create pri err!\n");
		exit(-1);
	}
	if(pid == 0)
	{
		//child pro
		printf("child pro executed\n");
	}
	if(pid > 0)
	{
		//parent pro
		printf("parent pro access\n");
	}
	
	exit(0);
}

在这个程序中,fork()创建一个新的进程,这个函数在父进程中返回值是子进程的pid,而在子进程中的返回值为0.

  1. exec函数族。
    我们知道fork()可以创建一个子进程,但是怎么让这个新的进程为我们服务呢?
    很简单,这个exec函数族提供了在一个进程中启动另一个进程的方法,当一个进程已经不能处理事件或者一个进程想执行另外一个程序,那么就可以调用exec函数族的任意一个函数。
	//测试:execlp
	#include <stdio.h>
	#include <stdlib.h>
	#include <unistd.h>
	
	int main(int argc, char **argv)
	{
		pid_t ret;
		if(fork() == 0){
			if((ret = execlp("ps","ps","-ef",NULL))<0)    //参数列举
				printf("execlp error\n");
		}
		exit(0);
	}
	
	//测试:execvp
	char *arr[3] = {"ls","-lh",NULL};                                 //构造指针数组
	ret = execvp("ls",arr);
  1. linux下的init进程:
    我们说init进程是linux所有进程的祖先进程,如果创建了一个子进程时父进程推出,那么子进程就成为了孤儿进程。由init接管。

  2. wait()和waitpid()。
    pid_t wait(int *status)函数时用于使父进程(也就是调用wait()的进程)阻塞,直到一个子进程结束或者该进程接到了一个指定的信号为止。status是一个整形指针,status不为空,则通过它可以获得子进程的结束状态。(双向参数)

    wait_t waitpid(wait_t pid,int *status,int options)指定为子进程收尸,wait()函数是waitpid的一个特例。
    pid > 0:只等待指定的进程。
    pid = -1:等待任何子进程退出,此时和wait()一样。
    pid == 0:等待其组ID等于调用进程组的任意进程。
    pid<-1:等待其组ID等于pid的绝对值的任何一个子进程。
    options:实现作业控制(WUNTRACED)或者不阻塞(WNOHANG)。
    返回值:已经结束运行的子进程的进程号,错误0

  3. 守护进程:就是后台服务进程(daemon进程)。
    创建步骤:
    创建子进程,父进程推出-》设置新回话-》改变工作目录为根目录-》重设文件权限掩码-》关闭文件描述符。

	int main()
	{
		pid_t pid;
		int i,fd;
		char *buf = "this is a Daemon\n";
		pid = fork(); //step1
		if(pid < 0){
			printf("error fork\n");
			exit(-1);
		}
		if(pid > 0){ //step2
			exit(0);
		}
		setsid();    //step3
		chdir("/");  //step4
		umask(0);	 //step5
		for(i=0; i<getdtablesize(); i++) //step 6
		{
			close(i);
		} 	//achieve Daemon process
		/daemon pro
		exit(0);
	}

最终的目的是摆脱原终端的控制、原会话组的控制、摆脱原进程组的控制。

  1. 进程的终止。
    正常终止:
    return 0;(main函数)
    exit(0);(标准库,清理IO(缓存))
    _exit(0)或者_Exit(0);(系统调用,不清楚io)
    最后一个线程调用pthread_exit()
    最后一个县城从启动线程返回。
    异常终止:
    调用abort
    接到一个杀死信号(kill -9 pid)
    最后一个线程取消请求做出响应。

  2. 进程的状态
    R:运行态。
    S:可中断的睡眠态。
    D:不可中断的睡眠态。
    T:停止。(收到SIGSTP、SIGTIN、SIGTOU信号)
    X:终止态。
    Z:僵尸态。

  3. c语言程序是如何调用系统命令的?
    fork()创建一个子进程,调用exec函数族中的其中一个函数,替换为对应的进程,运行完后wait()阻塞收尸。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

fjxx_psy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值