Linux基础总结

来源:互联网 发布:r语言mac如何读取文件 编辑:程序博客网 时间:2024/05/19 23:55

1.linux版本
内核版本 1991,芬兰大学生 www.kernel.org
发行版本 公司对内核版本进行软件/操作集成,更方便使用 选最稳定的版本

2.linux基本命令
目录:
cd 切换目录
pwd 显示当前路径
mkdir 创建目录
rmdir 删除目录

文件:
cp 拷贝文件
mv 粘贴/重命名文件
vi 打开文件编译器
more filename 查看文件内容(每次显示固定行)
cat filename 查看文件内容(一次性显示完)
head -n 查看文件前n行代码
tail -n 查看文件后n行代码
find filename 查看当前目录是否该文件
file filename 查看文件类型
chmod 修改文件权限
grep | 文本搜索

sed 替换文件中某些字符串的值
这里写图片描述

awk 把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各种分析处理。每接收文件的一行,然后执行相应的命令,来处理文本

进程:
ps 查看运行态的进程
ps -ef 查看运行态进程的所有信息
kill 挂起进程/结束进程
jobs 显示Linux中的任务列表及任务状态,包括后台运行的任务。

top 实时显示系统中各个进程的资源占用状况(CPU利用率/内存占用率)
这里写图片描述

管理:
useradd username 添加新用户
userdel username 删除用户
passwd name 修改用户密码
su username 切换用户
shutdown -h now现在关机 (root权限)
shutdown -r now现在重启 (root权限)
init 0 关机 (root权限)
init6 重启 (root权限)
halt关机 (普通用户)
reboot重启 (普通用户)

mail查看邮箱
这里写图片描述

网络:
netstat 显示网络连接、路由表和网络接口信息,可以让用户得知有哪些网络连接正在运作,可以查看进程占用的端口号 (root权限下使用)
这里写图片描述

lsof 显示系统打开的文件
这里写图片描述
打印了一堆我也不知道是什么的东东……

tcpdump 对网络上的数据包截获

其他常用命令:
ldd 查看程序用到的共享库
这里写图片描述

nm exename 查看exe文件中的偏移量

3.linux系统的目录结构

/boot linux内核启动的核心文件
/etc 配置文件
/bin 系统使用的命令
/lib 库文件
/home 用户的家目录,所有用户都在该目录下有以自己用户名命名的家目录
/mnt 用户临时挂载文件的挂载点
/proc 虚拟目录,存进程的信息,关机后消失
/dev linux的外部设备
/root 系统管理员的家目录

4.文件类型

-普通文件
d目录文件
p管道文件
l链接文件
c/b设备文件
s套接字文件

5.系统运行级别

0关机
1单用户模式,用于维护系统
2不带网络的多用户模式
3完整的多用户模式
4保留,用户可以自己定义
5图形化界面的多用户
6重启系统

6.vi文本编辑器
vi 文件名 打开文件
i 进入编辑文件
退出编辑模式
q 退出文本编辑器
!q 强制退出文本编译器
wq 保存退出
!wq 强制退出并保存修改内容
:set nu 加行号
:set nonu 去行号
nyy 拷贝n行
ndd 剪切n行
p 粘贴
ndd删除n行
u撤销

7.修改文件权限 chmod

u创建者 g主用户 o其他用户
r读权限4 w写权限2 x执行权限1
chmod u+x file 给该文件的创建者加可执行权限
chomd 0666 file 将文件的权限改为创建者/主用户/其他用户可读可写

8.g++和gcc有什么区别?
对于下面一段代码,分别创建test.c main.cpp

#include <stdio.h>int Add(int a, int b){    return a+b;}int main(){    printf("main:%x, add:%x\n", main, add);    return 0;}

<1>用gcc编译test.c,生成testc可执行文件
这里写图片描述
可以看到,gcc可以编译C语言代码,Add函数的符号名是按照编译C语言的方式处理的

<2>用g++编译test.c生成testc++可执行文件
这里写图片描述
可以看到,g++可以编译C语言代码,Add函数的符号名是按照编译C++的方式处理的

这里写图片描述
通过ls -l,查看文件详细信息,发现testc++比testc的文件大!

<3>用gcc编译main.cpp,生成mainc可执行文件
这里写图片描述
链接出错了!gcc默认是不能编译C++文件的,gcc不能自动链接C++的标准库stdc++,如果要用gcc编译C++文件,要手动链接++标准库

手动链接C++标准库,再来一次
这里写图片描述

链接成功!
这里写图片描述
可以看到,gcc默认不能编译C++代码,因为gcc不能自动链接C++标准库文件,手动链接库文件后,gcc按照C++方式处理程序

<4>用g++编译main.cpp生成mainc++可执行文件
这里写图片描述
可以看到,g++可以编译C++代码,按照C++方式处理程序

这里写图片描述
通过ls -l,查看文件详细信息,发现mainc比mainc的文件稍微大一点!

现在编译代码时用gcc,更确切的说他应该是一个驱动程序。它会根据代码的后缀名来判断调用C编译器还是C++编译器 (g++)。如果代码是后缀是.c,gcc会调用C编译器,去链接C标准库。如果代码后缀是.cpp,gcc会调用C++编译器,链接C++标准库

9.makefile文件
makefile简介:makefile是工程管理工具,按照代码的编译顺序逆向写makefile文件,编译时使用make命令编译makefile文件,方便编译。

这里写图片描述
注意:依赖关系和编译命令,用”换行和Tab键隔开”。

10.gdb常用调试命令

Linux系统上,默认的开发环境是realease版本,没有调试信息。编译时使用-g参数添加调试信息。如:gcc -o main main.c -g

进入调试:gdb main
查看代码:l
添加断点:b
查看断点信息:info break
删除断点:delete 断点号 (delete 1 删除断点号为1的断点)
运行程序:r
查看变量值:p (查看变量入口地址:p 函数名)
持续显示变量a的值:display a
下一步:n
继续运行,到下一个断点停止:c (continue)
进入函数:s
退出函数:finish
查看函数调用堆栈:bt
跟踪子进程:set follow-fork-make child
退出调试:q

11.core文件
在一个程序崩溃时,它会在指定目录(一般为当前目录)下生成一个core文件,主要是用来调试的。
core文件仅仅是一个内存映象(同时加上调试信息)。
core的默认大小是0,所以默认不产生core文件,因为默认是release版本。

core文件是在程序崩溃时才产生的!默认的core文件大小是0,此时即使程序崩溃,也不生成core文件。

查看core文件大小:ulimit -c
更改core文件大小:ulimit -c size
编译链接程序
运行程序
查看core文件:ls
进入core调试:gdb 文件名
开始调试:file ./test
退出调试:q

这里写图片描述

12.strace 跟踪程序运行中调用的系统调用
这里写图片描述

13.ltrace 跟踪库函数
这里写图片描述

14.库
库:预先编译好方法的集合

静态链接库(.a)和动态链接库(共享库.so)的区别?

静态链接库和动态链接库最大的区别是加载方法的时间不同。
静态链接库在编译时,将用到的方法加载进来,包含在可执行文件中(静态运行库中一个目标文件中只包含一个函数,因为加载静态库时候要将包含该函数的库方法都加载进来,太浪费空间)。

动态链接库在编译时对用到的方法做”需要用”标记,运行时将用到的方法加载到内存中。

对同一段程序,采用静态链接生成的exe文件比动态链接的exe文件大一些。

ldd 查看程序需要用到的共享库

15.进程
task_struct结构体中有两个指针,分别指向当前进程的生父和养父。初始值都是它的父进程。

<1>僵死进程
如果子进程先与父进程结束(子进程送SIGCHILD信号给父进程,父进程默认忽略该信号),父进程未获取子进程的状态信息,在未被init进程发现之前,子进程所处的状态是僵死态,此时的子进程就是僵死进程。僵死进程的生父指针和养父指针都是其父进程。当被init进程发现时,内核将其养父指针改为init进程,init负责清楚其占用的进程表,释放其资源。

如果在子进程时僵死状态时,父进程结束了,此时的僵死进程就变成了孤儿进程。内核将其生父指针改为init指针,init负责清楚其占用的进程表,释放其资源。子进程也结束了。

<2>孤儿进程
如果父进程先与子进程结束,此时子进程是孤儿进程,内核将其养父指针该为init进程,孤儿进程被init进程收养,init负责清楚其占用的进程表,释放其资源。子进程结束。

<3>fork

#include <stdio.h>int main(){    printf("A");    write(1,"B",1);    fork();    sleep(3);    return 0;}

结果是:BAA
B立即打印出来的,A在缓冲区中,fork()后,缓冲区的数据也被拷贝了一份,sleep时间到,程序结束时,刷新缓冲区,每个进程缓冲区中的A都被打印出来。

#include<stdio.h>int main(){    int i = 0;    for(; i<2; ++i)    {        fork();        printf("A\n");    }    return 0;}

结果是:AAAAAA

#include<stdio.h>int main(){    int i = 0;    for(; i<2; ++i)    {        fork();        printf("A");    }    return 0;}

结果是:AAAAAAAA

16.进程间通信
(1)管道
<1>性质:管道在内存中存取数据,磁盘上只保留管道的信息,故管道的大小恒为0。

只有在读、写端同时打开时,管道才能被正确打开,否则open一直阻塞。

代码测试管道大小
这里写图片描述

运行结果为65536(64K)

使用ulimit -a命令查看管道默认大小
这里写图片描述

因此,Linux系统上,管道默认大小为64K。

<2>无名管道
无名管道只能在父子进程间进行通信,pipe(int pipefd[2])创建出管道后,利用fork复制一个子进程。在子进程中写/读,在父进程中读/写。fd[0]读,fd[1]写

<3>有名管道
创建管道命令:mkfifo filename
程序运行过程中创建管道:

#include <sys/types.h>int mkfifo(const char *filename,mode_t mode);//管道名称,权限

<4>有名管道和无名管道的区别
无名管道:
–只能在有亲缘关系的进程(多为父子进程)间进行数据通信;
–无名管道是基于进程存在的,只能在程序运行时被创建,每次使用都要创建管道。

有名管道:
–可以在互不相关的进程之间实现通信;
–可以使用命令创建管道,通过管道所在的路径名定位到该管道,两个进程间通信的时候直接使用该管道,不用再创建。在文件系统中可以查看到该管道文件,但大小恒为0;

<5>管道的实现
这里写图片描述
管道总是从头指针head写,从尾指针tail读。写/读完成后,指针移动到合适位置。当头指针走到缓冲区的末尾时,又从另一端开始写(类似于循环,采取FIFO)

(2)信号量
作用:同步线程
手段:通过PV操作,控制程序的推进速度

临界资源:同一时间只允许有限个进程访问的资源
临界区:访问临界资源的代码段
原子操作:执行过程不能被打断

信号量是大于0的正整数值,信号量>1时,代表可以访问资源的进程数量;信号量为1/0,二元信号量。
P操作:(获取资源操作)原子-1
V操作:(释放资源操作)原子+1

(3)共享内存
共享内存:可以被映射到不同进程的内存空间,没有第三方空间
注意:要控制多个进程对同一共享内存的访问之间的同步(使用二元信号量/记录锁)

共享内存在栈的下方,紧靠着栈
mmap将一个文件的若干部分映射到进程地址空间(映射段与文件相关联)

(4)消息队列
消息队列是在两个不相关进程间传递数据的一种简单、高效方式,她独立于发送进程、接受进程而存在。

int msgget(key_t key, int msgflg);

因为消息队列独立于进程而存在,为了区别不同的消息队列,需要以key值标记消息队列,这样两个不相关进程可以通过事先约定的key值通过消息队列进行消息收发。例如进程A向key消息队列发送消息,进程B从Key消息队列读取消息。

16.线程
线程:程序内部中的一条执行路径。
(1)线程同步
<1>信号量  

sen_t sem;#include <semaphore.h>int sem_init(sem_t *sem, int pshared, unsigned int value);int sem_post(sen_t *sem);int sem_wait(sem_t *sem);int sem_destroy(sem_t *sem);

<2>互斥锁 互斥锁用于加锁互斥

pthread_mutex_t mutex;#include <semaphore.h>int pthrerad_mutex_init(pthread_t *mutex, NULL);int pthread_mutex_lock(pthread_mutex_t *mutex); int pthread_mutex_unlock(pthread_mutex_t *mutex); int pthread_destroy(pthread_mutex_t *mutex);

<3>条件变量  条件变量专注于等待
当达到某个条件时,执行某操作。通过设置条件达到同步进程。

17.并发运行与并行

并发运行
在单处理器多道程序设计系统中,在操作系统的管理下,所有正在运行的进程轮流使用CPU,每个进程允许占用CPU的时间非常短(比如10毫秒),这样用户根本感觉不出来CPU是在轮流为多个进程服务,就好像所有的进程都在不间断地运行一样,但实际上在任何一个时间内有且仅有一个进程占有CPU。

由于程序交替出现的顺序不同,所以每次结果几乎都不相同,很难发生预期的结果。

对临界区加锁,对进程同步。

并行
在多处理器多道程序设计系统中,在同一个时间段内,可以同时处理和处理器数目相同的程序,有时间上的重叠。

原创粉丝点击