目录
123
1文件系统的基本概念
文件系统是一种把数据组织成文件和目录的存储方式,提供了基于文件的存取接口,并通过文件权限控制访问。
VFS
Linux下的VFS:
VFS的作用就是采用标准的Unix系统调用读写位于不同物理介质上的不同文件系统。VFS是一个可以让open()、read()、write()等系统调用不用关心底层的存储介质和文件系统类型就可以工作的粘合层。在古老的DOS操作系统中,要访问本地文件系统之外的文件系统需要使用特殊的工具才能进行。而在Linux下,通过VFS,一个抽象的通用访问接口屏蔽了底层文件系统和物理介质的差异性。
etc就是一个标准的文件系统。/etc就是存放磁盘 系统配置的目录。VFS则是文件系统的接口。其他文件系统还有比如说NFS
2命令
Linux/Unix 的文件调用权限分为三级 : 文件所有者(Owner)、用户组(Group)、其它用户(Other Users)。
r 表示可读取,w 表示可写入,x 表示可执行,则
chmod:
rwx如果对应位置有字母,则对应二进制位为1,最终使用对应的八进制数来表示权限即r=4 w=2 x=1
例:chmod u+r a.txt 给文件所有者给予可读权
例:chmod 777 a.txt 所有用户所有权限
netstat
ps命令
ps -ef | grep 'mysqld'
pstree -p |grep 'itap' 查看进程数
1. 可以用 | 管道和 more 连接起来分页查看
命令:
ps -aux |more
2. 把所有进程显示出来,并输出到ps001.txt文件
命令:
ps -aux > ps001.txt
3. 输出指定的字段
命令:
ps -o pid,ppid,pgrp,session,tpgid,comm
pstree以树结构显示进程
$ pstree -p work | grep ad
3. pstack
pstack显示每个进程的栈跟踪
ps aux | grep Z
会列出进程表中所有僵尸进程的详细内容
free:用于显示内存状态
free指令会显示内存的使用情况,包括实体内存,虚拟的交换文件内存,共享内存区段,以及系统核心使用的缓冲区等。类似top命令第一部分的四五行
3主子进程
创建完子进程后,父进程继续运行app(即原来的进程)的代码,刚创建出来的子进程拥有和父进程完全一样的代码段,数据段,也就是说完完全全拷贝了一份父进程,和父进程完全一样。即clone父进程0-3G的内容,而3-4G的kernel只需要重新映射一下到物理地址的kernel即可。但是操作系统要如何区分这两个进程呢?答案就是进程ID,即pid。fork函数有两次返回,即调用一次,返回两次。在父进程返回子进程的pid,在子进程返回0,如果返回负数则表明fork失败。所以,我们根据返回值来判断当前进程是父进程还是子进程。
pid_t pid = fork();
getpid()返回的是当前进程的pid,getppid()返回的是当前进程的父进程的pid。那前面说的父进程的父进程是啥呢?是shell。因为我们是子啊shell中 ./ 运行程序才创建起刚才的父进程的,所以shell是该父进程的父进程。
fork之前的变量,读时共享,写时复制。
我们知道在unix/linux中,正常情况下,子进程是通过父进程创建的,子进程在创建新的进程。子进程的结束和父进程的运行是一个异步过程,即父进程永远无法预测子进程 到底什么时候结束。 当一个 进程完成它的工作终止之后,它的父进程需要调用wait()或者waitpid()系统调用取得子进程的终止状态。
孤儿进程:一个父进程退出,而它的一个或多个子进程还在运行,那么那些子进程将成为孤儿进程。孤儿进程将被init进程(进程号为1)所收养,并由init进程对它们完成状态收集工作。
僵尸进程:一个进程使用fork创建子进程,如果子进程退出,而父进程并没有调用wait或waitpid获取子进程的状态信息,那么子进程的进程描述符仍然保存在系统中。这种进程称之为僵死进程。(defunct)
1.当我们寻求如何消灭系统中大量的僵死进程时,答案就是把产生大 量僵死进程的那个元凶枪毙掉(也就是通过kill发送SIGTERM或者SIGKILL信号啦)。枪毙了元凶进程之后,它产生的僵死进程就变成了孤儿进 程,这些孤儿进程会被init进程接管,init进程(ppid 1)会wait()这些孤儿进程,释放它们占用的系统进程表中的资源,这样,这些已经僵死的孤儿进程 就能瞑目而去了。2.fork两次 《Unix 环境高级编程》8.6节说的非常详细。原理是将子进程成为孤儿进程,从而其的父进程变为init进程,通过init进程可以处理僵尸进程
4信号
C 库函数 void (*signal(int sig, void (*func)(int)))(int) 设置一个函数来处理信号,即带有 sig 参数的信号处理程序
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <stdlib.h>
#include <signal.h>
static void sig_child(int signo);
int main()
{
pid_t pid;
//创建捕捉子进程退出信号
signal(SIGCHLD,sig_child);
pid = fork();
if (pid < 0)
{
perror("fork error:");
exit(1);
}
else if (pid == 0)
{
printf("I am child process,pid id %d.I am exiting.\n",getpid());
exit(0);
}
printf("I am father process.I will sleep two seconds\n");
//等待子进程先退出
sleep(2);
//输出进程信息
system("ps -o pid,ppid,state,tty,command");
printf("father process is exiting.\n");
return 0;
}
static void sig_child(int signo)
{
pid_t pid;
int stat;
//处理僵尸进程
while ((pid = waitpid(-1, &stat, WNOHANG)) >0)
printf("child %d terminated.\n", pid);
}
SIGCHLD | 进程Terminate或Stop的时候,SIGCHLD会发送给它的父进程。缺省情况下该Signal会被忽略 |
Signal ()函数详细介绍 Linux函数_顾修忠的博客-CSDN博客_signal函数
5git
除了git还有svn、cvs这样的版本控制系统,它们的区别在于一个是分布式一个是集中式
集中式就是svn和csv这样的版本控制系统,分布式是git
区别在于集中式的版本控制系统每次在写代码时都需要从服务器中拉取一份下来,并且如果服务器丢失了,那么所有的就都丢失了,你本机客户端仅保存当前的版本信息,换句话说,集中式就是把代码放在一个服务器上集中管理,你的所有回滚等操作都需要服务器的支持。
分布式的区别在于,每个人的电脑都是服务器,当你从主仓库拉取一份代码下来后,你的电脑就是服务器,无需担心主仓库被删或者找不到的情况,你可以自由在本地回滚,提交,当你想把自己的代码提交到主仓库时,只需要合并推送到主仓库就可以了,同时你可以把自己的代码新建一份仓库分享给其它人。
像集中式它们都有一个主版本号,所有的版本迭代都以这个版本号为主,而分布式因为每个客户端都是服务器,git没有固定的版本号,但是有一个由哈希算法算出的id,用来回滚用的,同时也有一个master仓库,这个仓库是一切分支仓库的主仓库,我们可以推送提交到master并合并到主仓库上,主仓库的版本号会迭代一次,我们客户端上的git版本号无论迭代多少次,都跟master无关,只有合并时,master才会迭代一次。大名鼎鼎的github用的就是git系统来管理它们的网站,这里需要区分一下,github和git是两个东西,github是一个社区,git是一个服务系统,github只支持git分布式系统,所以故名成为github。
6概念
-
分布式 系统中的多个模块在不同服务器上部署,即可称为分布式系统,如Tomcat和数据库分别部署在不同的服务器上,或两个相同功能的Tomcat分别部署在不同服务器上
-
高可用 系统中部分节点失效时,其他节点能够接替它继续提供服务,则可认为系统具有高可用性
-
集群 一个特定领域的软件部署在多台服务器上并作为一个整体提供一类服务,这个整体称为集群。如Zookeeper中的Master和Slave分别部署在多台服务器上,共同组成一个整体提供集中配置服务。在常见的集群中,客户端往往能够连接任意一个节点获得服务,并且当集群中一个节点掉线时,其他节点往往能够自动的接替它继续提供服务,这时候说明集群具有高可用性
-
负载均衡 请求发送到系统时,通过某些方式把请求均匀分发到多个节点上,使系统中每个节点能够均匀的处理请求负载,则可认为系统是负载均衡的
-
正向代理和反向代理 系统内部要访问外部网络时,统一通过一个代理服务器把请求转发出去,在外部网络看来就是代理服务器发起的访问,此时代理服务器实现的是正向代理;当外部请求进入系统时,代理服务器把该请求转发到系统中的某台服务器上,对外部请求来说,与之交互的只有代理服务器,此时代理服务器实现的是反向代理。简单来说,正向代理是代理服务器代替系统内部来访问外部网络的过程,反向代理是外部请求访问系统时通过代理服务器转发到内部服务器的过程。
7boost库
Boost是一个功能强大、构造精巧、跨平台、开源并且完全免费的C++程序库。
C++11标准库中有三分之二来自Boost库,Boost库建立在“既有的实践”之上并提供参考实现,大大增强了C++的功能和表现力。
所以,为什么Linux程序员都喜欢编译依赖库的源码呢?我认为其中一个原因就是可以避免因为环境不一致而带来一些依赖库not found的问题。不同机器之间具体环境不同。比如某某库的版本,内核版本,还有机器硬件资源的不同。都可能导致直接使用已编译好的可执行文件不能正常使用,或不能发挥最大性能。。不同机器之间具体环境不同。比如某某库的版本,内核版本,还有机器硬件资源的不同。都可能导致直接使用已编译好的可执行文件不能正常使用,或不能发挥最大性能。。
1.ldd命令查看依赖