文章目录

  • 前言
  • 第一部分:博客知识点
    • (1)基础篇
      • Linux系统编程1:Linux中使用率最高的一些命令
      • Linux系统编程2:详解Linux中的权限问题
      • Linux系统编程3:基础篇之详解Linux软件包管理器yum
    • (2)入门篇
      • Linux系统编程4:入门篇之最强编辑器vim的使用攻略
      • Linux系统编程5:Linux系统编程5:入门篇之程序编译过程
      • Linux系统编程6:入门篇之如何拿下gdb调试器
      • Linux系统编程7:入门篇之Linux项目自动化构建工具
    • (3)进程入门
      • Linux系统编程9:进程入门之操作系统及其管理
      • Linux系统编程10:进程入门之系统编程中之进程
      • Linux系统编程11:进程入门之进程状态
      • Linux系统编程12:进程入门之进程的优先级及PR和NI
      • Linux系统编程13:进程入门之Linux中的环境变量的概念及其相关命令
      • Linux系统编程14:进程入门之进程地址空间
      • Linux系统编程15:进程控制之如何创建进程和写时拷贝技术
      • Linux系统编程16:进程控制之进程终止以及终止进程的三种情况
      • Linux系统编程17:进程控制之进程等待
      • Linux系统编程18:超详解进程程序替换及相关接口
      • Linux系统编程19:基础IO之Linux中的标准输入和输出
      • Linux系统编程20:基础IO之Linux是如何管理文件的
      • Linux系统编程21:基础IO之全缓冲和行缓冲的区别
      • Linux系统编程22:基础IO之掌握重定向的本质和使用dup2完成重定向
      • Linux系统编程23:基础IO之了解硬盘结构和链接
      • Linux系统编程24:基础IO之动静态库
      • Linux系统编程25:基础IO之亲自实现一个动静态库
      • Linux系统编程26:进程间通信之进程间通信的基本概念
      • Linux系统编程27:进程间通信之管道的基本概念
      • Linux系统编程28:进程间通信之共享内存和相关通信接口
      • Linux系统编程29:进程信号之什么是信号及signal函数
      • Linux系统编程30:进程信号之产生信号的四种方式
      • Linux系统编程31:进程信号之什么是信号的阻塞及相关术语
      • Linux系统编程32:进程信号之详解信号集操作函数
      • Linux系统编程33:进程信号之详解信号的捕捉过程,用户态和内核态
      • Linux系统编程34:进程信号之可重入函数,volatile关键字
      • Linux系统编程35:多线程之如何理解Linux中的线程以及轻量级进程LWP
      • Linux系统编程36:多线程之线程控制之pthread线程库
      • Linux系统编程37:多线程之什么是临界区和临界资源
      • Linux系统编程38:多线程之什么是线程同步以及条件变量函数
      • Linux系统编程39:多线程之基于阻塞队列生产者与消费者模型
      • Linux系统编程40:多线程之基于环形队列的生产者与消费者模型
      • Linux系统编程41:多线程之线程池的概念及实现
  • 第二部分:涉及的系统调用命令总结
    • (1)进程部分
    • (2)基础IO部分
    • (3)进程间通信部分
    • (4)进程信号部分
    • (5)多线程部分
  • 第三部分:重要代码

前言

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

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

第一部分:博客知识点

(1)基础篇

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

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

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

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

(2)入门篇

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

Linux系统编程5:Linux系统编程5:入门篇之程序编译过程

Linux系统编程6:入门篇之如何拿下gdb调试器

Linux系统编程7:入门篇之Linux项目自动化构建工具

(3)进程入门

Linux系统编程9:进程入门之操作系统及其管理

Linux系统编程10:进程入门之系统编程中之进程

Linux系统编程11:进程入门之进程状态

Linux系统编程12:进程入门之进程的优先级及PR和NI

Linux系统编程13:进程入门之Linux中的环境变量的概念及其相关命令

Linux系统编程14:进程入门之进程地址空间

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

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

Linux系统编程17:进程控制之进程等待

Linux系统编程18:超详解进程程序替换及相关接口

Linux系统编程19:基础IO之Linux中的标准输入和输出

Linux系统编程20:基础IO之Linux是如何管理文件的

Linux系统编程21:基础IO之全缓冲和行缓冲的区别

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

Linux系统编程23:基础IO之了解硬盘结构和链接

Linux系统编程24:基础IO之动静态库

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

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

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

Linux系统编程28:进程间通信之共享内存和相关通信接口

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

Linux系统编程30:进程信号之产生信号的四种方式

Linux系统编程31:进程信号之什么是信号的阻塞及相关术语

Linux系统编程32:进程信号之详解信号集操作函数

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

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

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

Linux系统编程36:多线程之线程控制之pthread线程库

Linux系统编程37:多线程之什么是临界区和临界资源

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

Linux系统编程39:多线程之基于阻塞队列生产者与消费者模型

Linux系统编程40:多线程之基于环形队列的生产者与消费者模型

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);}}elseprintf("进程创建失败\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}elseprintf("进程创建失败\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);}elseprintf("进程创建失败\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=read(fd,buffer,sizeof(buffer)-1);if(ret>0){buffer[ret]='\0';printf("服务端接受到客户端消息:%s\n",buffer);}else if(ret==0)//如果客户端退出,将会读到文件结束,所以服务端也要退出{printf("客户端已经下线,服务端下线\n");break;}else {perror("读取失败\n");break;}}}
}

client.c

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>int main()
{int fd=open("fifo",O_WRONLY);//直接打开管道文件if(fd>=0){ char buffer[64];//从键盘读入数据到这个缓冲区while(1){ printf("客户端-请输入消息:");ssize_t ret=read(0,buffer,sizeof(buffer)-1);//从键盘读入数据if(ret>0){ buffer[ret]='\0';write(fd,buffer,ret);//读入ret个数据就向管道中写入ret个数据}}}
}

8:理解共享内存
server.c

#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <unistd.h>
#include <sys/shm.h>#define PATHNAME "tmp"
#define PROJ_ID 88
#define  SIZE 4096int main()
{key_t k=ftok(PATHNAME,PROJ_ID);printf("key值:%#X\n",k);int shmid=shmget(k,SIZE,IPC_CREAT | IPC_EXCL|0666);if(shmid<0){perror("creat failed");return 1;}char* shmaddr=shmat(shmid,NULL,0);//挂接,注意强转while(1)//每1s打印一次{sleep(1);printf("%s\n",shmaddr);}shmdt(shmaddr);//脱离shmctl(shmid,IPC_RMID,NULL);//释放return 0;
}

client.c

#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <unistd.h>
#include <sys/shm.h>#define PATHNAME "tmp"
#define PROJ_ID 88
#define  SIZE 4096int main()
{key_t k=ftok(PATHNAME,PROJ_ID);printf("key值:%#X\n",k);int shmid=shmget(k,SIZE,0);//服务端已经申请了,写成0直接获取if(shmid<0){perror("creat failed");return 1;}char* shmaddr=shmat(shmid,NULL,0);//挂接,注意强转int i=0;while(i<26){shmaddr[i]=97+i;每隔5s依次输入a,b,c...........................i++;sleep(5);}shmdt(shmaddr);//脱离return 0;
}

9:理解signal函数

#include <stdio.h>
#include <unistd.h>
#include <signal.h>void handler(int sig)
{printf("catch a sin : %d\n",sig);}int main()
{signal(2,handler);//一旦捕捉到2号信号,将会执行handler函数内的操作while(1){printf("I Am runnng now...\n");sleep(1);}return 0;}

10:理解信号集操作函数

#include <stdio.h>
#include <unistd.h>
#include <signal.h>void handler(int sig)
{printf("获得信号:%d\n",sig);}void print_pending(sigset_t* pending)
{int i=1;for(i=1;i<=31;i++){if(sigismember(pending,i)){printf("1");//只要i信号存在,就打印1}else {printf("0");//不存在这个信号就打印0}}printf("\n");
}int main()
{signal(2,handler);//捕捉sigset_t pending;//定义信号集变量sigset_t block,oblock;//定义阻塞信号集变量sigemptyset(&block);sigemptyset(&oblock);//初始化阻塞信号集sigaddset(&block,2);//将2号信号添加的信号集sigprocmask(SIG_SETMASK,&block,&oblock);//设置屏蔽关键字int cout=0; while(1){sigemptyset(&pending);//初始化信号集sigpending(&pending);//读取未决信号集,传入pendingprint_pending(&pending);//定义一个函数,打印未决信号集sleep(1);cout++;if(cout==10)//10s后解除阻塞{printf("解除阻塞\n");sigprocmask(SIG_SETMASK,&oblock,NULL);}}
}

11:理解线程的创建,等待等

#include <stdio.h>
#include <unistd.h>
#include <pthread.h>void* new_thread(void* arg)
{while(1){printf("我是新线程,我的线程id是%p\n",pthread_self());sleep(5);int a=1/0; //浮点异常}
}int main()
{pthread_t tid;//线程的IDpthread_create(&tid,NULL,new_thread,(void*)"我是新线程");while(1){ printf("-----------------------------------------------------------\n");printf("我是主线程,我的线程id是:%p,新线程的id是%p\n",pthread_self(),tid);void* ret;//获取退出码pthread_join(tid,&ret);printf("主线程阻塞等待新线程,退出码码为%d\n",(int)ret);break;}}

12:理解互斥锁

#include <stdio.h>
#include <unistd.h>
#include <pthread.h>int tickets=1000;pthread_mutex_t lock;//申请一把锁void scarmble_tickets(void* arg)
{long int ID=(long int)arg;//线程IDwhile(1)//多个线程循环抢票{pthread_mutex_lock(&lock);//那个线程先到,谁就先锁定资源if(tickets>0){usleep(1000);printf("线程%ld号抢到了一张票,现在还有%d张票\n",ID,tickets);tickets--;pthread_mutex_unlock(&lock);//抢到票就解放资源}else {pthread_mutex_unlock(&lock);//如果没有抢到也要释放资源,否则线程直接退出,其他线程无法加锁break;}}}int main()
{int i=0;pthread_t tid[4];//4个线程IDpthread_mutex_init(&lock,NULL);//初始化锁for(i=0;i<4;i++){pthread_create(tid+1,NULL,scarmble_tickets,(void*)i);//创建4个线程}for(i=0;i<4;i++){pthread_join(tid+1,NULL);//线程等待}pthread_mutex_destroy(&lock);//销毁锁资源return 0;
}

13:理解条件变量

#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <stdlib.h>pthread_mutex_t lock;//锁
pthread_cond_t cond;//条件void* thread_a(void* arg)//其他线程被唤醒
{const char* name=(char*)arg;//线程名字while(1){pthread_cond_wait(&cond,&lock);//一直在等待条件成熟printf("%s被唤醒了\n=================================================\n",name);}}void* thread_1(void* arg)//让线程1唤醒其他线程
{const char* name=(char*)arg;while(1){sleep(rand()%5+1);//随机1-5秒唤醒pthread_cond_signal(&cond);printf("%s现在正在发送信号\n",name);}}int main()
{pthread_mutex_init(&lock,NULL);//初始化锁pthread_cond_init(&cond,NULL);//初始化条件pthread_t t1,t2,t3,t4,t5;//创建两个线程pthread_create(&t1,NULL,thread_1,(void*)"线程1"); pthread_create(&t2,NULL,thread_a,(void*)"线程2"); pthread_create(&t3,NULL,thread_a,(void*)"线程3"); pthread_create(&t4,NULL,thread_a,(void*)"线程4"); pthread_create(&t5,NULL,thread_a,(void*)"线程5"); pthread_join(t1,NULL);pthread_join(t2,NULL);pthread_join(t3,NULL);pthread_join(t4,NULL);pthread_join(t5,NULL);pthread_mutex_destroy(&lock);pthread_cond_destroy(&cond);//销毁条件}

14:生产者与消费者模型

Linux系统编程39:多线程之基于阻塞队列生产者与消费者模型

Linux系统编程40:多线程之基于环形队列的生产者与消费者模型

15:理解线程池

上。

【README】Linux系统编程必读:本专栏内容提要以及系统调用接口总结相关推荐

  1. 外网访问arm嵌入式linux_嵌入式Linux系统编程——文件读写访问、属性、描述符、API

    Linux 的文件模型是从 Unix 的继承而来,所以 Linux 继承了 UNIX 本身的大部分特性,然后加以扩展,本章从 UNIX 系统接口来描述 Linux 系统结构的特性. 操作系统是通过一系 ...

  2. 4. linux调用文件计算阶乘前5项和_嵌入式Linux系统编程——文件读写访问、属性、描述符、API

    Linux 的文件模型是从 Unix 的继承而来,所以 Linux 继承了 UNIX 本身的大部分特性,然后加以扩展,本章从 UNIX 系统接口来描述 Linux 系统结构的特性. 操作系统是通过一系 ...

  3. 攻克 Linux 系统编程

    课程亮点 完整学习路线图,系统掌握核心知识点 内核源码深入分析,知其然更知所以然 高频问题全面汇总,精准定位症结所在 八大主题商业案例,实操中获得拔高提升 专家推荐 曾与宇文拓共事五年,他对技术的钻研 ...

  4. Linux系统编程:验证kernel内核缓存区大小->4096字节

    Linux系统编程:验证kernel内核缓存区大小->4096字节 李四老师 于 2018-04-04 00:40:04 发布 2778 收藏 2 分类专栏: [Linux编程] [C/C++编 ...

  5. linux系统发送信号的系统调用是,linux系统编程之信号:信号发送函数sigqueue和信号安装函数sigaction...

    信号发送函数sigqueue和信号安装函数sigaction sigaction函数用于改变进程接收到特定信号后的行为. sigqueue()是比较新的发送信号系统调用,主要是针对实时信号提出的(当然 ...

  6. linux系统编程需要什么,若想成为一名Linux下编程高手,必须能对各种系统调用有透彻的了解...

    原标题:若想成为一名Linux下编程高手,必须能对各种系统调用有透彻的了解 什么是系统调用? Linux内核中设置了一组用于实现各种系统功能的子程序,称为系统调用.用户可以通过系统调用命令在自己的应用 ...

  7. Linux系统编程——线程私有数据

    在多线程程序中.常常要用全局变量来实现多个函数间的数据共享.因为数据空间是共享的,因此全局变量也为全部线程共同拥有. 測试代码例如以下: #include <stdio.h> #inclu ...

  8. vbs结束进程代码_物联网学习教程—Linux系统编程之进程控制

    Linux系统编程之进程控制 一.结束进程 首先,我们回顾一下 C 语言中 continue, break, return 的作用: continue: 结束本次循环 break: 跳出整个循环,或跳 ...

  9. linux线程并不真正并行,Linux系统编程学习札记(十二)线程1

    Linux系统编程学习笔记(十二)线程1 线程1: 线程和进程类似,但是线程之间能够共享更多的信息.一个进程中的所有线程可以共享进程文件描述符和内存. 有了多线程控制,我们可以把我们的程序设计成为在一 ...

最新文章

  1. 波音737-800座位图哪个好_澳媒一张图揭秘,飞机选座秘诀!经济舱最舒适的位置在这儿...
  2. [云炬创业学笔记]第三章商业创意的发掘与评估测试1
  3. tensorflow:Multiple GPUs
  4. 在VS 2010上搭建Windows Phone 7开发平台
  5. SpringBoot:@ConfigurationProperties注解使用与源码
  6. 正确的java学习顺序--刚入门的同学可以看这里
  7. 计算机导入文件格式,电脑如何打开zip格式文件|电脑打开zip格式文件的方法
  8. 拳王虚拟项目公社:微店闲鱼怎样自动化卖虚拟商品,虚拟资源自动化收钱项目
  9. qq和微信文件保存路径
  10. win10重装系统,屏幕亮度调节失效修复
  11. 骑士 cms宝塔环境配置问题
  12. 计算机超级工作站,【八核高性能计算超级计算机CAECADCAM有限元超级工作站】.docx...
  13. [文档] 软件需求规格说明书
  14. Android接入穿山甲SDK并实现开屏广告
  15. cmd命令行下怎样切换目录
  16. 家用计算机的辐射,电脑的辐射有多大?
  17. 中国移动光猫怎么进网页服务器,中国移动光猫设置方法(192.168.1.1进不了光猫)...
  18. 20个常用的Linux工具命令
  19. 人工神经网络技术及应用,人工神经网络发展前景
  20. pandas笔记1 --pandas处理mat表格文件

热门文章

  1. Ubuntu查看和写入系统日志
  2. Permission denied(publickey)的解决办法:github/gitlab仓库与本地关联
  3. 股票价格与利息率之间的关系
  4. android照片编辑软件,Adobe推Android版Photoshop照片编辑软件
  5. Vm虚拟机安装Ubuntu和VmTools
  6. css实现“加号”效果
  7. 【转】 java的声音技术与AudioStream (包括在java应用程序中循环播放声音)
  8. union和union all的性能差别居然这么大
  9. 易到用车面试总结(android)
  10. 自己做量化交易软件(8)通通量化自编公式-仿通达信大智慧公式指标