Linux-----进程(多任务)

一、什么是进程

(一)进程的含义?

进程是一个程序执行的过程,会去分配内存资源,cpu的调度

(二)进程分类:

        1、交互式进程
        2、批处理进程   shell脚本 
        3、 守护进程 

(三)进程与程序的区别

    1)程序是永存,进程是暂时的
    2)进程有程序状态的变化,程序没有
    3)进程可以并发,程序无并发
    4)进程与进程会存在竞争计算机的资源
    5)一个程序可以运行多次,变成多个进程

一个进程可以运行一个或多个程序

(四)进程的作用:

并发并行(各执行各的)


(五)进程的状态:

3个状态,就绪→执行态→阻塞(等待,睡眠)基本操作系统
    linux中的状态,运行态,睡眠态,僵尸态,暂停态。

(1)运行态(running):进程占有处理器正在运行。

(2)就绪态(ready):进程具备运行条件,等待系统分配处理器以便运行。

(3)阻塞态(blocked):又称为或睡眠(sleep)态,指进程不具备运行条件,正在等待某个事件的完成。

(4)僵尸态(zombie):子运行完,父没运行完,子进程会以终止状态保持在进程表中,并且会一直在等待父进程读取才能退出。

(5)孤儿态:父运行完,子没运行完,子处于托管状态,加重系统负担

(6)创建态:进程正在被创建,但尚未转到就绪态。

(7)终止态:进程已经完成执行并准备被撤销。

进程的状态:

PROCESS STATE CODES
       Here are the different values that the s, stat and state output specifiers 
	   (header "STAT" or "S") will display to describe the state of a process:

               D    uninterruptible sleep (usually IO) //不可中断的睡眠态
               R    running or runnable (on run queue) // 运行态
               S    interruptible sleep (waiting for an event to complete)//可中断的睡眠态
               T    stopped by job control signal      // 暂停态
               t    stopped by debugger during the tracing
               W    paging (not valid since the 2.6.xx kernel)
               X    dead (should never be seen)
               Z    defunct ("zombie") process, terminated but not reaped by its parent

       For BSD formats and when the stat keyword is used, additional characters may be displayed:

               <    high-priority (not nice to other users)
               N    low-priority (nice to other users)
               L    has pages locked into memory (for real-time and custom IO)
               s    is a session leader
               l    is multi-threaded (using CLONE_THREAD, like NPTL pthreads do)
               +    is in the foreground process group

     R  --- 运行态 
	 D  --- 不可中断 睡眠态
	 S  --- 可中断 睡眠态 
	 T  --- 暂停态 
	 Z  --- 僵尸态 

cb
struct task_struct {
    PID,             //进程标识符
	PPID,            //父进程ID号  parent 
	当前工作路径     //chdir
	umask            //0002
	进程打开的文件列表 //文件IO中有提到
	信号相关设置       //处理异步io, ---段错误
	用户id,组id
	进程资源的上限
}

二、进程管理的命令

1、top  //类似Windows的下任务管理器 

2、ps -eLf | head -1   //可以观察到 PID PPID 

3、ps -eLf | grep a.out  //查看a.out 信息 //可以观察到 PID PPID

4、ps -aux | grep a.out  //可以查看进程 的状态 

5、pstree  //进程树

6、pstree -sp pid号 //查看指定的进程的关系

7、kill //给进程发信号     //kill -l  //查看可以发送的信号 

操作: 
      将子进程杀死 。结束子进程,父进程还在,但是父进程并没有对子进程"收尸"
8、进程的pid号 ppid号    getpid    getppid 

操作: 
      将父进程杀死 。子进程 还在 ,父进程不在 ---- 孤儿进程 
                             ---- 此时由init进程 收养 

特殊:
      孤儿进程 
           子进程 还在,父进程不在
      僵尸进程 
          子进程 结束,父进程还在,且父进程并未"收尸"
          僵尸态进程有危害 

三、函数

pid_t fork(void);
       功能:
          创建子进程 (通过复制调用进程)
       参数:
          void 
       返回值:
          成功 
              在父进程中 返回子进程的pid号
              在子进程中 返回0
          失败 
             -1 && errno 被设置
             
     pid号:
          pid 本质上就是一个数值 
          正整数 1 

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

int main(int argc, const char *argv[])
{
	pid_t pid = fork();

	if(pid<0)
	{
		perror("fork fail");
		return -1;
	}
while(1)
{
	if(pid > 0)
	{
		printf("hello\n");
	}else if(pid ==0)
	{
		printf("world\n");
	}
}
	
	return 0;
}


1、子进程先运行和是父进程先进程,顺序不确定。
    变量不共享。

2、子进程复制父进程的0到3g空间和父进程内核中的PCB,但id号不同。

3、此时,父子进程各自拥有独立的4g内存空间 (32位的系统)

4、功能

           通过该函数可以从当前进程中克隆一个同名新进程。
          克隆的进程称为子进程,原有的进程称为 父进程。
          子进程是父进程的完全拷贝。
          复制之后,
          子进程和父进程 各自拥有自己的 用户空间(进程空间)
          子进程和父进程的执行过程是从fork函数之后执行。
          
          子进程与父进程具有相同的代码逻辑。


5、返回值:int 类型的数字。
            在父进程中:成功 返回值是子进程的pid号 >0
                        失败 返回-1;
            在子进程中:成功 返回值 0
                        失败 无

6、注意:
      1.创建好之后,父子进程的运行顺序是不确定 ---全部取决于 操作系统的调度 

注意:
   1.父子进程创建好之后,各自拥有独立4G内存空间(32位系统)
   2.他们的数据相互独立,父进程或子进程对数据的修改,不会相互影响,只会对各自造成影响     
 

(一)、练习

如果两次fork同时前后执行,会生成几个进程?
    fork();
    fork();
    他们之间的关系如何表示,
    有多少个子进程,
    有没有孙进程?    
 

2、fork()&&fork()||fork();    //总共几个进程

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

int main(int argc, const char *argv[])
{
	fork()&&fork()||fork();
	while(1);
		sleep(1);	
	return 0;
}

3、练习:
   自己分别定义一个 static的变量 static int a = 0;
                    全局变量     int b = 1;
                    堆区         int *p = (int *)malloc(sizeof(int));
                                 *p = 2;
(做修改)父进程中 做加1的操作 ,
       子进程中做加2的操作
       sleep(1);
分别打印,查看效果!
 

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

int main(int argc, const char *argv[])
{
	pid_t pid = fork();
	static int a =
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值