READMELinux系统编程必读:本专栏内容提要以及系统调用接口总结

Posted 快乐江湖

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了READMELinux系统编程必读:本专栏内容提要以及系统调用接口总结相关的知识,希望对你有一定的参考价值。

前言

本专栏是Linux系统编程学习笔记,内容主要是Linux的认识,命令,进程,IPC,信号,文件和多线程等,点击标题可进行跳转

  1. 第一部分:主要是该篇博客涉及到的核心知识点
  2. 第二部分:Linux系统编程中会涉及到大量系统调用,所以会以思维导图的方式总结
  3. 第三部分:将博客中重要的代码操作拿出来,方便复习,练习

第一部分:博客知识点

(1)基础篇

1:Linux系统编程1:Linux中使用率最高的一些命令

  • 命令lscdtouchmkdirrmcpmvcatgreptarless是读者必须必须要掌握的,他们的各种参数一定要滚瓜烂熟,因为日后他们的使用率几乎高达80%
  • 掌握如何在Linux中添加用户及设置用户密码
  • 理解Linux文件结构
  • 理解相对路径与绝对路径

Linux系统编程2:详解Linux中的权限问题

  • Linux中的超级用户和普通用户
  • su和sudo的区别
  • Linux中的权限管理
  • 权限的两种表示方法:8进制表示法字符表示法
  • 使用chmod修改权限
  • 目录的读写还有执行权限如何理解
  • 使用chown更改文件拥有者,使用chgrp更改文件所属组
  • 理解umask并会用umask设置默认权限
  • 理解粘滞位

Linux系统编程3:基础篇之详解Linux软件包管理器yum

此篇博客的内容较为简单,但是很重要——如何在Linux中安装软件,需要大家掌握yum的一些常用用法

(2)入门篇

Linux系统编程4:入门篇之最强编辑器vim的使用攻略

  • vim编辑器的三种模式
  • vim基本操作

Linux系统编程5:Linux系统编程5:入门篇之在Linux下观察C/C++程序编译过程 && gcc/g++使用详解

  • 在Linux下体会C语言文件的编译过程
  • 掌握gcc和g++
  • 了解函数库

Linux系统编程7:入门篇之Linux项目自动化构建工具-Make/Makefile的超强使用指南

  • 学会使用makefile

(3)进程入门

Linux系统编程9:进程入门之操作系统为什么这么重要以及它是如何实现管理的

  • 理解操作系统的作用
  • 明白系统调用接口和库的关系

Linux系统编程10:进程入门之系统编程中最重要的概念之进程&&进程的相关操作&&使用fork创建进程

  • 操作系统是如何管理进程的
  • PCB与task_struct的关系
  • 什么是进程
  • 掌握系统调用接口fork
  • fork为什么有两个返回值

Linux系统编程11:进程入门之详细阐述进程的一些状态&&区分僵尸状态和孤儿状态&&动图演示

  • 进程的一些状态的理解
  • 什么是僵尸进程和孤儿进程

Linux系统编程12:进程入门之进程的优先级及PR和NI&&如何修改进程优先级

  • 如何理解进程的优先级
  • PR和NI是什么

Linux系统编程13:进程入门之Linux中的环境变量的概念及其相关命令(export;env等)&&main函数的参数

  • 环境变量的理解
  • 如何查看和设置环境变量
  • main函数的三个参数掌握
  • 环境变量全局属性

Linux系统编程14:进程入门之Linux进程中非常重要的概念之进程地址空间-原来我们看到的地址全部是虚拟的

  • C/C++内存空间复习
  • 深刻理解进程地址空间
  • 页表的作用
  • 虚拟内存和物理内存

Linux系统编程15:进程控制之如何创建进程和写时拷贝技术

  • 对于写时拷贝的理解

Linux系统编程16:进程控制之进程终止以及终止进程的三种情况

  • 进程退出时的三种情况
  • exit的return的区别
  • _exit和exit的区别

Linux系统编程17:进程控制之进程等待&&为什么进程需要被等待&wait方法和waitpid方法&&阻塞和非阻塞等待

  • 进程为什么需要被等待
  • 阻塞式等待和非阻塞式等待的区别
  • wait方法
  • waitpid方法的第二个参数statuts的理解,它是怎样获取到退出码的,以及低16位的变化情况

Linux系统编程18:超详解进程程序替换&exec函数的一些用法

  • 理解进程程序替换
  • 6个进程程序替换的接口的掌握
  • 重点理解参数的一些意义

Linux系统编程19:基础IO之了解Linux中的标准输入和输出以及相关的系统调用接口(如write,read等)

  • 理解标准输入,标准输出和标准错误
  • 掌握open,write,read和close的用法

Linux系统编程20:基础IO之从内核代码深刻理解Linux是如何管理文件及文件描述符的本质是什么

  • 深刻理解文件描述符fd
  • 0,1,2号文件都代表什么
  • 从关闭1号文件角度理解重定向
  • 从内核角度理解操作系统如何管理文件
  • 为什么说一切皆文件

Linux系统编程21:基础IO之全缓冲和行缓冲的区别及深刻理解缓冲区及其作用

  • 全缓冲和行缓冲的区别
  • 理解C语言提供的用户级缓冲区

Linux系统编程22:基础IO之掌握重定向的本质和使用dup2完成重定向

  • 掌握重定向的本质
  • 使用dup2完成重定向

Linux系统编程23:基础IO之了解硬盘物理和逻辑结构及明白inode的本质和掌握软硬链接及其区别

  • 理解硬盘的物理结构和逻辑结构
  • 通过叙述如何查找文件,创建文件,删除文件依次达到对inode和block的理解
  • 掌握软硬链接的本质及其他们的区别

Linux系统编程24:基础IO之在Linux下深刻理解C语言中的动静态库以及头文件和库的关系

  • 深刻理解动态库和静态库的区别
  • 明白库与头文件的关系

Linux系统编程26:进程间通信之进程间通信的基本概念

  • 明白我们是怎样给别人提供库的
  • 在静态库中如何打包.o文件,如何将头文件和库封装在一个文件中,以及编译时的-I,-L,-l三个参数头代表什么意思
  • 在动态库中编译时加入的选项和打包时用的选项,以及最终编译时如何将动态库添加到动态库的环境变量里面

Linux系统编程27:进程间通信之管道的基本概念和匿名管道与命名管道及管道特性

  • 进程间通信的本质

Linux系统编程27:基础IO之亲自实现一个动静态库

  • 理解管道是什么
  • 理解管道的四大特性
  • 使用管道完成进程间的通信
  • 匿名管道和命名管道的区别

Linux系统编程28:进程间通信之共享内存和相关通信接口(ftok,shmget,shmctl,shmat,shmdt)

  • 理解管道和共享内存的区别
  • 掌握共享内存系列的接口的用法

Linux系统编程29:进程信号之什么是信号及signal函数

  • 信号的处理动作都有哪些
  • 掌握signal函数的用法,理解其形参及返回值的含义

Linux系统编程30:进程信号之产生信号的四种方式(Core Dump,kill,raise)

  • 四种产生信号的方式及其特点
  • 了解core dump
  • 了解SIGALRM信号

Linux系统编程31:进程信号之什么是信号的阻塞及相关术语(递达,未决,pending位图,handler位图)

  • 信号相关术语:未决,阻塞,递达
  • 信号在内核中的表示:pending位图,block的位图的深刻理解

Linux系统编程32:进程信号之详解信号集操作函数(sigset_t ,sigpending,sigprocmask)

  • 了解sigset_t类型
  • 掌握信号集操作函数的用法

Linux系统编程33:进程信号之详解信号的捕捉过程,用户态和内核态及其切换,sigaction和signal

  • 理解用户态和内核态
  • 信号是什么是处理和捕捉的——详细叙述信号捕捉过程

Linux系统编程34:进程信号之可重入函数,volatile关键字的作用和SIGHLD

  • 理解可重入函数
  • 理解volatile关键字的作用
  • 如何使用SIGCHLD信号清理僵尸进程

Linux系统编程35:多线程之如何理解Linux中的线程以及轻量级进程LWP

  • 理解Linux中的线程
  • 理解进程和线程的关系
  • 理解LWP
  • 线程的优缺点

Linux系统编程36:多线程之线程控制之pthread线程库(线程创建,终止,等待和分离)

  • 掌握线程创建,终止,,等待和分离的pthread库函数
  • 深化对Linux线程的理解

Linux系统编程37:多线程之什么是临界区和临界资源以及如何使用mutex互斥锁

  • 理解临界区和临界资源
  • 理解互斥锁的作用
  • 理解互斥锁的实现原理
  • 可重入函数与线程安全
  • 死锁相关

Linux系统编程38:多线程之什么是线程同步以及条件变量函数

  • 线程的同步和互斥的理解
  • 掌握条件变量函数的使用

Linux系统编程41:多线程之线程池的概念及实现

  • 理解线程池,亲自实现线程池
  • 线程池概念相关的优缺点

第二部分:涉及的系统调用命令总结

(1)进程部分

在这里插入图片描述

(2)基础IO部分

在这里插入图片描述

(3)进程间通信部分

在这里插入图片描述

(4)进程信号部分

在这里插入图片描述

(5)多线程部分

在这里插入图片描述

第三部分:重要代码

1:理解fork的作用

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

int main()
{
	prinf("还没有执行fork函数的本进程为:%d\\n",getpid());
	pid_t=fork();//其返回值是pid类型的
	sleep(1);
	
	if(ret>0)//父进程返回的是子进程ID
	{
		while(1)
		{
			printf("----------------------------------------------------------------\\n");
			printf("我是父进程,我的id是:%d,我的孩子id是%d\\n",getpid(),ret);
			sleep(1);
		}
	}
	else if(ret==0)//子进程fork返回值是0
	{
		while(1)
		{
			printf("我是子进程,我的id是%d,我的父亲id是%d\\n",getpid(),getppid());
			sleep(1);
		}
	}
	else
		printf("进程创建失败\\n");
		
	sleep(1);
	return 0;
}

2:理解僵尸状态

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{
   // printf("还没执行fork函数时的本进程为:%d\\n",getpid());
    pid_t ret=fork();//其返回值类型是pid_t型的
    sleep(1);
    if(ret>0)//父进程返回的是子进程ID
    {
      while(1)
      {
        printf("----------------------------------------------------\\n");
        printf("父进程一直在运行\\n");
        sleep(1);
      }
    }
    else if(ret==0)//子进程fork返回是0
    {
      int count=0;
      while(count<=10)
      {
        printf("子进程已经运行了%d秒\\n",count+=1);
        sleep(1);
      }
      exit(0);//让子进程运行10s
    }
    else
      printf("进程创建失败\\n");

    sleep(1);
    return 0;
}


3:理解进程等待及waitpid第二个参数

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{
    pid_t ret=fork();//其返回值类型是pid_t型的
    sleep(1);
    if(ret>0)//父进程返回的是子进程ID
    {
		printf("父进程正在等待子进程死亡\\n");
		int st=0;
		pid_t rec=waitpid(ret,&st,0);//阻塞
		if(rec==ret)//如果返回值是子进程id,等待成功
		{
			printf("等待成功\\n");
			if(WIFEXITED(st))//如果为真,正常退出
			{
				printf("正常退出且退出码为%d\\n",WEXITSTATUS(st));
			}
			else
			{
				printf("异常退出,信号值为%d\\n",st&0x7f);
			}
			
			
		}
		else
		{
			printf("等待失败\\n");
			exit(0);
		}
	}
    else if(ret==0)//子进程fork返回是0
    {
      int count=1;
      while(count<=10)
      {
        printf("子进程[%d]已经运行了%d秒\\n",getpid(),count);
		count++;
        sleep(1);
      }
      exit(3);
    }
    else
      printf("进程创建失败\\n");

    sleep(1);
    return 0;
}



4:理解进程程序替换

//myprocess.c
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{
  int count=0;
  while(count<5)
  {
    printf("Hello World\\n");
    sleep(1);
    count++;
  }
  printf("%s\\n",getenv("myenv"));
 return 0;
}

//test.c
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
  char* env[]={"myenv=you_can_see_this_env",NULL};
  printf("替换函数前\\n");
  execle("./myprocess.exe","myprocess.exe",NULL,env);
  printf("替换函数后\\n");

}


5:理解文件描述符

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

int main()
{
  int fd1=open("log1.txt",O_WRONLY);//打开错误
  int fd2=open("log2.txt",O_WRONLY|O_CREAT);//打开成功
  int fd3=open("log3.txt",O_WRONLY|O_CREAT);//打开成功
  int fd4=open("log4.txt",O_WRONLY|O_CREAT);//打开成功
  int fd5=open("log5.txt",O_WRONLY);//打开错误


  printf("%d\\n",fd1);
  printf("%d\\n",fd2);
  printf("%d\\n",fd3);
  printf("%d\\n",fd4);
  printf("%d\\n",fd5);
}


6:理解匿名管道

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

int main()
{
  int  pipefd[2]={0};
   pipe(pipefd);
  pid_t id=fork();
  if(id==0)//child
  {
    close(pipefd[0]);
    const char* msg="This is the data that the child process wrote";
    while(1)
    {
        write(pipefd[1],msg,strlen(msg));
        sleep(1);
    }     
  }
  else//father
  {
    close(pipefd[1]);
    char buffer[64];
    while(1)
    {
        ssize_t ret=read(pipefd[0],buffer,sizeof(buffer)-1);
        if(ret>0)//判断是否读到
        {
            buffer[ret]='\\0';//加上结束标志,便于输出
            printf("The father process got the information:%s\\n",buffer);
        }
    }
  }
  return 0;
}

7:理解命名管道
server.c

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main()
{
  umask(0);//屏蔽命令行umask干扰
  if(mkfifo("./fifo",0666)==-1)//如果mkfifo返回值是-1,创建失败
  {
    perror("打开失败");
    return 1;
  }
  int fd=open("fifo",O_RDONLY);//服务端以只读的方式打开管道文件
  if(fd>=0)
  {
    char buffer[64];
    while(1)
    {
      printf("客户端正在接受消息\\n");
      printf("############################\\n");
      ssize_t ret=专栏必读王道考研408计算机网络+网络编程万字笔记题目题型总结注意事项目录导航和思维导图

专栏必读王道考研408操作系统+Linux系统编程万字笔记题目题型总结注意事项目录导航和思维导图

专栏必读Java基础教程和数据结构思维导图和内容导航

专栏必读王道考研408计算机网络+网络编程万字笔记题目题型总结注意事项目录导航和思维导图

专栏必读数据库系统概论第五版(王珊)专栏学习笔记目录导航

(王道408考研操作系统)第二章进程管理-第一节1:进程PCB及其特征