嵌入式开发学习日志(linux系统编程--进程(1))Day27

函数补充:

1、【sprintf】:

形式:【int sprintf(char *str, const char *format, ...);】

        sprintf(数组,“%s %s”,字符串1,字符串2);

可以将字符串一和字符串2拼接在一起,装在数组中;

eg:(1)打开指定目录下的所有文件(递归法)

2、【fprintf】:

                 int fprintf(FILE *stream, const char *format, ...);

【FILE *stream】;文件流指针;

【const char *format, ...】需要输入文件的内容;

        一般配合fflush(fp);函数一起使用,用于刷新写入的内容;

eg:(2)设计一个程序,动态生成两个进程,分别向相同的文件中 写入不同的数据,要表明是两个进程同时写入的数据。 父进程1123 186 16:02:10,, 子进程1124 188 16:02:15

#include <dirent.h>
#include <stdio.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>
int times() {
  time_t tm;
  tm = time(NULL);
  return tm;
}

int wenjianzonghe() {
  DIR *dir = opendir("/proc");
  if (NULL == dir) {
    perror("opendir");
    return 1;
  }
  int i = 0;
  int t = 0;
  while (1) {
    struct dirent *info = readdir(dir);
    if (NULL == info) {
      break;
    }

    if (info->d_name[0] >= 48 && info->d_name[0] <= 57) {
      ++i;
    }
  }
  closedir(dir);
  return i;
}

int main(int argc, char **argv) {
  FILE *fp = fopen("1.txt", "w");
  if (NULL == fp) {
    perror("fopen");
    return 1;
  }
  pid_t ret = fork();
  if (ret > 0) {
    while (1) {

      int num = wenjianzonghe();
      long int t = times();
      struct tm *tminfo = localtime(&t);

      fprintf(fp,"父进程 %d  %d  %d-%d-%d %d:%d:%d\n", getpid(), num,
             tminfo->tm_year + 1900, tminfo->tm_mon + 1, tminfo->tm_mday,
             tminfo->tm_hour, tminfo->tm_min, tminfo->tm_sec);
             fflush(fp);
             
      sleep(3);
    }
  }

  if (ret == 0) {
    while (1) {
      int num = wenjianzonghe();
      long int t = times();
      struct tm *tminfo = localtime(&t);
      fprintf(fp,"子进程 %d  %d  %d-%d-%d %d:%d:%d\n", getpid(), num,
             tminfo->tm_year + 1900, tminfo->tm_mon + 1, tminfo->tm_mday,
             tminfo->tm_hour, tminfo->tm_min, tminfo->tm_sec);
             fflush(fp);
          
      sleep(6);
    }
  }

  else 
  {
    perror("fork");
    return 1;
  }
  fclose(fp);
  return 0;
}

 3、man -k //模糊搜索 

        【man -k  输入函数的前面部分】

二、进程

1、进程的定义

定义:进程是一个程序执行的过程中,会去分配内存资源和CPU的调度;

作用:让操作系统并发执行,希望在短的时间内,多个任务同时进行

pcb  是一个结构体,process control block  print circuit board
vim -t
task_struct 

PID,进程标识符
    当前工作路径   chdir             //了解
    umask  0002                         //了解
    进程打开的文件列表  文件IO中有提到
    信号相关设置 处理异步io,

    用户id,组id
    进程资源的上限
    ulimit -a,显示资源上限。

 2、进程和程序的区别

程序:静态
存储在硬盘中代码,数据的集合;

进程:动态
程序执行的过程,包括进程的创建、调度、消亡;

.c ----> a.out-----> process(pid)(程序运行起来便有进程)
1)程序是永存,进程是暂时的
2)进程有程序状态的变化,程序没有
3)进程可以并发,程序无并发
4)进程与进程会存在竞争计算机的资源
5)一个程序可以运行多次,变成多个进程
一个进程可以运行一个或多个程序

 3、内存的分布

      0-3G,是进程的空间,3G-4G是内核的空间,虚拟地址
        虚拟地址 *  物理内存和虚拟内存的地址 映射表 1page=4k

        MAP /share共享库         

        Stack栈         // 8Mb

        heap堆           //动态内存空间,由程序员申请可以使用的空间;

        data数据        //存放全局变量和静态变量;

        code代码段,//只读;

MMU:虚拟空间

        1、透明;

        2、隔离;

        3、权限

映射表

(1)映射表将虚拟内存的地址转换为物理内存的地址;

(2)映射表通常由页表(Page Table)组成,它记录了虚拟地址到物理地址的映射关

        系;

(3)一个页面大小通常为4k(4036字节);

4、进程的分类

        1、交互式进程
        2、批处理进程   shell脚本 (批量执行一次命令)
        3、 守护进程 (程序走起来不需要输入,eg:杀毒类软件、启动输入法)

5、进程的状态

        3个状态,就绪→执行态→阻塞(等待,睡眠)基本操作系统 

        linux中的状态,运行态,睡眠态,僵尸,暂停态。

 6、查询进程的相关命令【ps aux】

6.1查询进程的相关命令【ps aux】

        【ps aux】

       6.1.1 查看进程相关信息

                1.就绪态、运行态 R
                2.睡眠态、等待态
                        可唤醒等待态 S
                        不可唤醒等待态 D
                3.停止态 T
                4.僵尸态 Z
                5.结束态

1.ps aux        查看进程相关信息

        |less              屏满等待

        |grep 51283        51283为进程的PID,寻找该PID

2.     pstree        查看进程树

        pstree -p       查看进程树,显示PID

6.2查询进程的相关命令【top】

        根据CPU占用率查看进程相关信息

6.3关闭进程的相关命令【kill】

kill -2 PID  15

发送信号+PID对应的进程,默认接收者关闭

其中【-2】代表发送几号信号(信号编号),可以用【kill - l】查看64中信号

当不输入信号编号时,默认为15号信号;

-2 委婉提醒关闭;

-9是强制关闭;

killall -9 进程名
发送信号 进程名对应的所有进程
killall a.out

7、 进程的调度,进程上下文切换

内核主要功能之一就是完成进程调度, 硬件,bios,io,文件系统,驱动调度算法,

 other,idle
rr,fifo
宏观并行:在一个时间段多个任务和进程是同时进行的
微观串行:在一个时间点只能一条一条指令执行

实时操作系统:规定时间内完成

分时操作系统:尽量在规定时间内完成(如Linux、Windows等)

后台任务

1、先来先服务;   2、短任务优先    3、优先级,高优先级先行     4、时间片轮转

 

进程上下文切换:就是值指调度器要切换CPU给另一个进程的时候,要保存当前进

      程的状态,然后加载打开一个新的进程这样的一个过程。

 

8、进程的作用

1、并发性:允许多个进程同时运行,提高了CPU利用率和系统响应速度;

2、稳定性:如果一个进程发生错误,通常不会影响到其他进程,这提高了系统的稳定

                    性;

三、进程相关函数 

1、fork()

形式:

                    pid_t fork(void);

功能:通过该函数可以从当前进程中克隆一个同名新进程。
  克隆的进程称为子进程,原有的进程称为 父进程。
  子进程是父进程的完全拷贝。
  子进程的执行过程是从fork函数之后执行。

该函数一次调用,会返回两次;

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

在调用之后注意:

①是父进程先运行还是子进程先运行,顺序不确定;

②变量不共享;

③子进程与父进程具有相同的代码逻辑。

④子进程的执行过程是从fork函数之后执行。

⑤子进程复制父进程的0到3g空间和父进程内核中的PCB,但id号不同(子的id比父大)

⑥子进程与父进程谁先消亡是随机的,谁跑得快谁先消亡

eg:使用fork函数,观察父子进程运行状态,并且验证父子进程的变量不共享;

2、getpid()

形式:

                        pid_t getpid(void);

功能:
                获得调用该函数进程的pid

返回值:

                返回值为当前进程的pid号;

3、getppid()

形式:

                        pid_t getppid(void);

功能:
                获得调用该函数父进程的pid

返回值:

                返回值为当前进程父进程的pid号;

4、

四、写时复制

写时拷贝:为了提高效率,Linux采用写时拷贝技术,即只有在父或子进程修改数据时才真正复制。

优点:提高效率、创建子进程速度快、开的空间少、回收速度快。

五、进程的终止

(1)主动退出

1)main 中return
2)exit(), c库函数,会执行io库的清理工作,关闭所有 的流,以及所有打开的文件。已经清理函数(atexit)。
3)_exit,_Exit 会关闭所有的已经打开的文件,不执行清理函数。
4) 主线程退出
5)主线程调用pthread_exit


(2)异常终止

1)【abort()】:该函数禁止应用层调用,发生严重错误系统调用;
2)【signal   kill pid】:有权限的发送信号(内存访问错误则发送信号结束)
3)最后一个线程被pthread_cancle

1、exit     库函数


退出状态,终止的进程会通知父进程,自己是如何终止的。如果是正常结束(终止),则由exit传入的参数。如果是异常终止,则有内核通知异常终止原因的状态。任何情况下,父进程都能使用wait,waitpid获得这个状态,以及资源的回收。
                                void exit(int status) 
exit(1);
功能:
让进程退出,并刷新缓存区
参数:
status:进程退出的状态
返回值:
缺省

2._exit    系统调用


                void _exit(int status);
功能:
让进程退出,不刷新缓存区
参数:
status:进程退出状态
返回值:
缺省

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值