This is my study note of linux.

基本概念

1
库是一种二进制文件,由编译产生。

库的种类

  • 静态库
    1
    2
    3
    4
    5
    6
    7
    静态库编译的时候会被链接到目标代码里,所以程序运行的时候不需要静态库了,体积比较大。静态库以lib开头,以.a结尾。
    静态库制作步骤:
    1.编写或准备源码
    2.将源码编译生成.o
    3.使用ar命令创建静态库 arr cr libmylib.a mylib.o
    4.测试库 gcc test.c -lmylib -L .
    其中-l+库文件名 -L +文件路径
  • 动态库
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    动态库编译的时候不会被链接到目标代码里,运行的时候仍需动态库的存在,体积较小。动态库以lib开头,以.so结尾。
    动态库制作流程:
    1.编写或准备源码
    2.编译源码生成.o
    3.使用gcc生成.so, 例gcc -shared -o libmylib.so mylib.o
    4.测试库 gcc test.c -lmylib -L .
    其中-l+库文件名 -L +文件路径
    配置动态库环境的方法:
    1.直接将生成的文件放到/lib或者/usr/lib里面
    2.使用export命令:export LD_LIBRARY_PATH = $LD_LIBRARY_PATH:路径 (本方法只对当前终端有效)
    3.修改ubuntu下的配置文件/etc/ld.so.conf,在这个文件中加入动态库所在的位置,然后使用ldconfig更新目录。

进程

孤儿进程

1
父节点已经结束但是子节点没有结束,这样的子节点叫做孤儿进程。会被init进程领养,等到结束后释放。

僵尸进程

1
子进程已经结束但是父进程不释放对应的资源,这样的子进程叫做僵尸进程。

wait函数

1
2
3
pid_t wait(int *status);           // 成功返回子进程的pid,失败返回-1
WIFEXITD(status); // 如果子进程正常退出,则宏为真
WEXITSTATUS(status); // 如果子进程正常退出,则该宏定义的值为进程退出值

守护进程

1
2
3
4
5
6
7
守护进程运行在后台,不跟任何控制终端关联。多个进程组成进程组,一个会话可以有多个进程组。
如何创建一个守护进程?
1.init进程的子进程,即变为孤儿进程(fork一个新进程,父进程用exit退出)
2.不跟任何控制终端交互(使用setsid函数,创建一个新的会话)
3.调用chdir函数,将当前工作目录改成根目录,增强程序的健壮性
4.重设umask文件掩码
5.关闭文件描述符

管道

无名管道

1
2
无名管道只能实现有亲缘关系间的通信。
pipe(fds[2]); // 传出两个文件描述符,0读1写

有名管道

1
2
可以实现没有任何关系之间进程的通信。
mkfifo函数或者命令

信号

信号的发送

1
2
3
4
5
6
7
8
1.kill函数
int kill(pid_t pid, int sig);

2.raise函数(自己给自己发)
int raise(int sig);

3.alarm函数(类似定时器,时间到了就发alarm信号)
unsigned int alarm(unsigned int seconds);

信号的接收

1
2
3
4
5
6
7
1.保证进程不停止
while、sleep、pause

2.接收 signal(sig, handle);
①signal(SIGINT, SIG_IGN); // 忽略SIGINT信号
②signal(SIGINT, SIG_DFL); // 代表执行默认操作
③signal(SIGINT, fun); // 代表执行自己设定的函数fun

共享内存

1
2
3
4
5
6
7
8
9
10
11
12
1.创建共享内存
shmget(key_t key, size_t size, int shmflg);
// 如果key为宏,则key是0x00000000部分,若是ftok创建,则不是0x00000000开始,同时shmflg参数要|IPC_CREAT。
2.命令查看共享内存
ipcs -m
3.将共享内存映射到用户空间,减少访问内核空间的次数
void *shmat(int shmid, const void *shmaddr, int shmflg);
4.删除共享内存
int shmdt(const void *shmaddr);
// 将映射出来的shmat内存删除,内核空间内存不动
5.删除共享内存标识符
int shmctl(int shmid, int cmd, struct shmid_ds *buf);

消息队列

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
1.创建消息队列
int msgget(key_t key,int msgflg);
2.删除消息队列
int msgctl(int msqid, int cmd, struct msqid_ds *buf);
3.命令查看消息队列
ipcs -q
4.消息队列发送
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
5.消息结构体
struct msgbuf
{
long mtype;
char mtext[1];
}
6.消息队列接收
ssize_t msgrcv(int msqid, const void *msgp, size_t msgsz,long msgtyp,int msgflg);

信号量

1
2
3
4
5
6
7
8
9
1.获得信号量ID
int semget(key_t key, int nsems, int semflg);
2.初始化信号量
int semctl(int semid, int semnum, int cmd, union semun arg);
cmd:
1.IPC_STAT(获取信号量的属性)
2.IPC_SET(设置信号量的属性)
3.lPC_RMID(删除信号量)
4.SETVAL(设置信号量的值)