苏嵌实训——day14(上)

简介: 苏嵌实训——day14(上)

一、IO


1.1 fseek


头文件: #include 
原型:int fseek(FILE *stream, long offset, int whence);
功能:读写指针的偏移
参数:
    stream:目标文件流指针
    offset:如何偏移,偏移多少
        如果为负数,代表向前偏移,如果偏移出了文件的开头,会返回报错。
        如果该数为正数,代表向后偏移,如果偏移除了文件的末尾,会扩大文件,用'\0'来填,那么此类文件称为空洞文件
        注意:如果偏移后没有对其进行任何写入操作,内核认为该偏移无效,不会扩大文件大小
     whence:基准位置  ------》根据哪一个位置进行偏移
     SEEK_SET:根据文件开头进行偏移
     SEEK_CUR:根据用户当前位置进行偏移
     SEEK_END:根据文件末尾进行偏移 
返回值:
    成功返回0
    失败返回-1


#include <stdio.h>
char ch = 0;
int main(int argc, char const *argv[])
{
    FILE *fp = fopen("./1.txt","r+");
    if(NULL == fp)
    {
        perror("fopen");
        return -1;
    }
    //文件中的数据为helloworld
    //从文件的末尾向后偏移----空洞文件
    fseek(fp,2000,SEEK_END);
    fputc('a',fp);
    ch = fgetc(fp);
    printf("ch = %c\n",ch);
    fseek(fp,1,SEEK_CUR);   //从当前位置向后偏移一个字节
    ch = fgetc(fp);
    printf("ch = %c\n",ch);
    fseek(fp,-1,SEEK_END);
    ch = fgetc(fp);
    printf("ch = %c\n",ch);
    return 0;
}


1.2 sprintf


头文件: #include 
原型:int sprintf(char *str, const char *format, ...);
功能:向一个固定的地址存放字符串(一般用于字符串的拼接)
参数:
     str:要存放格式化完成的字符串的地址
     format:格式化字符串
     ...:可变参数(一般放置变量)
返回值:
    成功返回输出的字节个数
    失败返回负数


#include <stdio.h>
int main(int argc, char const *argv[])
{
    char name[20] = "zhangsan";
    int age = 18;
    char sex = 'w';
    char phone[12] = "12345678900";
    char buf[123] = {0};
    sprintf(buf,"name:%s--age:%d--sex:%c--phone:%s",name,age,sex,phone);
    printf("buf = %s\n",buf);
    return 0;
}


1.3 snprintf


头文件: #include 
原型:int snprintf(char *str, size_t size, const char *format, ...);
功能:按照固定的大小去格式化字符串输出到字符地址中
参数:
     str:要存放格式化完成的字符串的地址
     size:大小(规定要写入str这片地址中的字节大小)
     format:格式化字符串
     ...:可变参数(一般放置变量)
返回值:
    成功返回输出的字节个数
    失败返回负数


1.4 fprintf


头文件: #include 
原型:int fprintf(FILE *stream, const char *format, ...);
功能:格式化输出字符串到文件中(一般用于书写日志文件)
参数:
     stream:目标文件流指针
     format:格式化字符串{固定的字符串和占位符}
     ...:可变参数(一般放置变量)
返回值:
    成功返回输出的字节个数
    失败返回负数


#include <stdio.h>
int main(int argc, char const *argv[])
{
    char name[20] = "zhangsan";
    int age = 18;
    char sex = 'w';
    char phone[12] = "12345678900";
    FILE *fp = fopen("./1.txt","w");
    if(NULL == fp)
    {
        perror("fopen");
        return -1;
    }
    fprintf(fp,"name:%s--age:%d--sex:%c--phone:%s",name,age,sex,phone);
    return 0;
}


二、缓冲区


预定义流
在程序开始之前,创建三个文件描述符,分别为0,1,2对应的标准输入,标准输出,标准错误输出,同时也在其基础上封装了三个预定义流指针
标准输入:stdin --->键盘文件
标准输出:stdout --->终端文件
标准错误输出:stderr --->终端文件


#include <stdio.h>
int main(int argc, char const *argv[])
{
    char buf[123] ={0};
   // fgets(buf,123,stdin);   //从标准输入流中读取数据
    //printf("buf = %s\n",buf);
    //标准输出
   // fprintf(stdout,"helloworld%s","123123");
    //标准错误输出
    fprintf(stderr,"helloworld%s","123123");
    while(1);
    return 0;
}


2.1 缓冲区


缓冲区是什么?标准IO在文件IO的基础上封装的一片存放数据的地址(一般用来存放不着急得数据),等到缓冲区这个地址得数据存满,或者说程序员手动刷新缓冲区,空间中得数据会被调用文件IO操作。


全缓冲:一般对文件得操作,缓冲区大小为4096个字节。(页)

刷新缓冲区得条件:

1.缓冲区满刷新缓冲区

2.程序结束刷新缓冲区

3.程序员手动刷新缓冲区


fflush

头文件:#include 
原型:int fflush(FILE *stream);
功能:刷新缓冲区
参数:目标文件流指针
返回值:
    成功返回:0
    失败返回:EOF


#include <stdio.h>
#include <unistd.h>
int main(int argc, char const *argv[])
{
    FILE *fp = fopen("1.txt","w");
    if(NULL == fp)
    {
        perror("fopen");
        return -1;
    }
#if 0
    while(1)
    {
        fprintf(fp,"helloworld");
        usleep(10000);
    }
#endif
    fprintf(fp,"helloworld");
    fflush(fp);
    while(1);
    return 0;
}


2.2 行缓冲:


只有两个行缓冲,标准输入,标准输出,行缓冲得大小为1024个字节

刷新行缓冲得条件:

1.缓冲区遇到\n则刷新缓冲区

2.缓冲区满则刷新缓冲区

3.当标准输入和标准输出一方要使用缓冲区时,正在使用得一方需要让出缓冲区,给另一方使用

4.fflush刷新缓冲区

5.程序结束


#include <stdio.h>
int main(int argc, char const *argv[])
{
    int i = 0 ;
    //验证缓冲区大小
    for(i = 0; i < 1025;i++)
    {
        printf("1");  //每次向准备输出输入一个字节
    }
    //验证\n刷新缓冲区
    printf("hello world\n");
    char buf[123] = {0};
    printf("helloworld1");
    scanf("%s",buf);
    while(1);
    return 0;
}


2.3 无缓冲


一般为标准错误输出,一般用于比较着急得数据,所以不会进入缓冲区,直接调用文件IO

一般使用方式:fprintf(stderr,“hello world”);

后续报错信息:使用这种方式

文件IO和标准IO得区别

文件IO属于系统调用,由操作系统提供,速度快,但是频繁调用文件IO会降低内核得工作效率,并且移植性较差。

标准IO是由标准c库所提供,是在文件IO得基础上封装出来得API接口,移植性高并且在文件IO得基础上封装了一片缓冲区,降低了文件IO得调用次数,提高了内核得效率。

所以说我们得根据情况来使用者这两种IO模型。


三、进程


任务:目标结果

程序:是为了完成任务,编写得一段代码,是一个静态得


3.1 进程的概念


进程是程序为了完成任务执行得一次过程,是一个动态的,进程被称为资源分配的最小单位,因为每一个进程在启动初期,都会申请一个0-4G的虚拟空间。

这个空间分为两个部分,0-3G用户空间,3-4G是内核空间,0-3G是进程之间独有的空间,互不影响。3-4G属于多进程共享的空间(后续于进程间通讯使用),因为进程用户空间相互独立,互不影响,所以安全性较高。还会申请一个PCB进程控制块,是一个结构体,tast_struct里面存储了所有的进程资源

如:PC程序计数器,堆栈,文件描述符,进程的状态,进程号等。

操作系统启动时会自动出创建三个进程:

0:负责引导系统启动,也会创建一个1号进程 --》init进程

1:负责初始化硬件,回收资源

2:负责资源的分配,系统的调度

进程之间存在这个一种竞态。执行速度是不一定的,所以父子进程结束的快慢也是不一定的。


3.2 进程的调度机制:


0a2653c851af460fa595bd959398a8f1.png


3.3 进程的状态


2d65d23f6d4748949b924e4057485923.png


3.4 进程的标志


进程号(PID):linux分配的进程的编号,每个进程都不一样,方便管理

进程在结束的时候,会释放进程号的所有权,其它进程等待它释放一段时间后分配,并不会结束后立马区分配。


3.5 进程相关的命令:


1.pstree


以树的形式显示所有的进程

如果加上-p参数会显示进程号


2.ps -ef


主要查看父子进程关系

PID 进程ID PPID 父进程ID


3. ps aux


主要查看进程的状态


0a2653c851af460fa595bd959398a8f1.png


进程的状态:
1.R:运行态
2.S: 休眠态
3.I:空闲态
4.T:停止态
5.Z:僵尸态
1. <:优先级高进程
2. N:优先级低
3. l:该进程中包含线程
4. +:前台进程
5. s:会话首进程
4. ps -ajx
主要用于查看家族关系


PGID:进程组ID

SID:会话ID


5. top -htop


动态查看进程信息:主要查看进程CPU占用率


6. jobs


查看用户后台进程列表

ctrl + z :会将前台运行的进程暂停保存到后台

fg:会将后台暂停的进程恢复到前台运行

fg + %序列号:将指定的后台暂停程序恢复到前台运行


bg:会将后台暂停程序在后台运行

bg + %序列号:制动哪一个进程

可执行程序名 + &:将进程运行在后台


相关文章
|
2天前
|
Java 关系型数据库 MySQL
|
2天前
|
SQL 前端开发 数据库
|
2天前
|
算法 前端开发 Java
思途实训-day03-04
思途实训-day03-04
|
网络协议
苏嵌实训——day17(下)
苏嵌实训——day17(下)
|
网络协议 数据安全/隐私保护 网络架构
苏嵌实训——day17(上)
苏嵌实训——day17(上)
苏嵌实训——day17(上)
|
消息中间件 存储 Linux
苏嵌实训——day16(上)
苏嵌实训——day16(上)
苏嵌实训——day16(上)
|
安全 调度
苏嵌实训——day15(上)
苏嵌实训——day15(上)
|
存储 Linux 程序员
苏嵌实训——day13(上)
苏嵌实训——day13(上)
苏嵌实训——day13(上)