Linux系统总结

1 Linux目录框架

dev/ 设备文件
bin/ 系统程序
sbin/ 管理员系统程序
lib/ 系统程序库文件
etc/ 系统程序和大部分应用程序的全局配置文件

2 Linux的常用命令

指令功能
pwd查看当前位置
cd进入某个文件夹
cd 文件目录名相对当前位置下的文件目录名(相对路径)
cd . .(中间没空格)返回上一级文件目录
cd /进入到根目录
cd /home/xxx进入到指定路径(绝对路径)
cd ~进入到当前用户的文件目录(家目录)
ls查看文件目录包含的文件名
ls -a查看文件目录下包含的文件名、目录名、隐藏文件
ls -l查看文件目录下包含的文件名、目录名的详细信息
mkdir创建文件夹
touch仅创建文件
gedit 文件名编辑文件内容
vi/vim编辑文件内容
rm删除文件
rm -r 文件名删除文件夹
cp 文件名(路径下的某个文件) 目的路径复制文件
cp -r 文件目录 目的路径复制文件夹
mv 文件 目的路径剪切文件
tar xvf xxx.tar把xxx.tar解压出来
tar cvf xxx.tar 目录压缩
tar xvf xxx.tar -C 路径把xxx.tar解压到指定路径下
sudo管理权限下放
sudo passwd root修改用户密码(需要下放权限)
su root切换用户
clear清屏
方向键上下查看之前执行的命令
Tab键自动补全
sudo apt-get update更新本地的源
sudo apt-get install xxx安装xxx软件
sudo apt-get remove xxx卸载xxx软件
sudo apt-get upgrade更新本地的软件
gcc 需要编译的C文件只能生成一个文件a.out
gcc 需要编译的C文件 -o 编译后生成的文件名可以生成多个可执行文件
man帮助手册
chmod 权限(权限以 4,2,1 的组合) 文件/目录名修改文件/目录的权限
cat 文件名在不打开文件的同时查看文件的内容
ifconfig查看当前系统的网络信息
ping 域名测试系统是否和外网相通
ln -s 源文件/链接文件创建链接文件
history查看系统里执行的历史命令
find 路径 -name 文件名在指定的路径下按照你指定的文件类型,查找指定的文件名
grep -n “关键字” 文件名把文件中的关键字包括所在行号都检索出来
grep -v “关键字” 文件名反向查询,将除关键字外的都检索出来
echo 内容将内容输出到终端
echo xxx >> 文件名将xxx写入到文件中,再次写入为换行追加写入
echo xxx > 文件名将xxx写入到文件中,再次写入清空写
chown (-R -h) 文件名更改属主
env查看当前系统的环境变量

3 Linux常用工具

3.1 vim的使用

(1) vim 文件名        如果文件存在就打开,不存在就创建并打开
(2) vim 文件名 +行号   打开文件并且光标跳转到你指定的行
vim的四种模式:
(1) 命令行模式
  ① 复制:(n)yy  n:代表光标从当前所在行往下复制多少行
  ② 粘贴:p
  ③ 删除:(n)dd  n:代表光标从当前所在行往下删除多少行
  ④ 撤销:u
  ⑤ gg:从光标所在位置跳转到代码开头
  ⑥ G:从光标所在位置跳转到代码结尾
  ⑦ gg=G:代码自动对齐
(2) 插入模式
  按 i 进入插入模式
(3) 底行模式
  先按esc,再输入:
    w:保存不退出
    w!:强制保存
    q:不保存退出,如果文件改动,按q后会提示内容已改动,无法退出
    q!:强制退出不保存
    wq:保存并退出
    x:如果修改了就保存退出,如果没有修改就直接退出
    /关键字:如果有就高亮显示
          去除高亮就是noh
    字符串替换:%s/源字符串/替换的字符串/g
(4) 可视模式
  在命令行模式下按 v 进入
  在可视模式下可以进行  删除(d) 复制(y)和 剪切(x)

3.2 gcc的使用

一个.c文件需要经过下面四个步骤:
(1) 编译预处理
处理宏定义,以#开头的(头文件和条件编译)
gcc -E xxx.c -o xxx.i
(2) 编译
将编译预处理后的文件做语法检查
gcc -S xxx.i -o xxx.s
(3) 汇编
将汇编代码翻译为机器指令,一条汇编代码对应一条机器指令
as xxx.s -o xxx.o
(4) 链接
头文件包含只是告诉了头文件的路径,而文件真正的头文件是封装到库里的,链接就是找到真正的库函数
gcc xxx.o -o xxx

3.3 静态库与动态库

静态库的后缀名为.a
动态库的后缀名为.so
-I 跟使用到的头文件路径、
gcc xxx.c -o xxx -I /xxx/xxx
(1) 库名
开头必须为lib,中间才是库名
例如:libfun.a 库名为fun
(2) 静态库
gcc -c *.c -I ../include
ar -rc libxxx.a *.o
gcc main.c libxxx.a -I ../include
(3) 动态库
gcc -c *.c -I ../include -fpic
gcc -fpic -shared *.o -o libxxx.so
gcc main.c -I ../include -lfun(必须要提前把libfun.so复制到/lib或者/usr/lib下)
(4) 动态库与静态库的区别:
静态库在编译的时候代码和静态库一起编译生成了可执行的二进制文件
动态库是在执行二进制文件的时候采取指定的路径下找库文件
(5) 动态库路径的配置
① 直接在终端执行配置执行(临时配置,关闭终端即失效)
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:库的路径
② 将配置的环境变量写入文件中
sudo gedit /etc/profile
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:库的路径
配置好后重启虚拟机或者source /etc/profile即可生效

3.4 gdb调试工具

(1) gdb 文件名(前提需要使用gcc -g 文件名生成的a.out)
(2) l:查看源码信息
(3) break/b:设置断点(就是代码运行到这里就停止了)
   b 行号/函数名
(4) r 开始运行
(5) info b:查看断点信息
(6) print/p :查看变量当前的值
(7) n:单步运行,遇到函数,他不会跳到函数的内部去运行,会直接拿到函数的运行结果
(8) s:单步运行,遇到函数,他会跳到函数的内部去运行,会直到把函数内部的函数运行完毕才会结束。
(9) quit;退出gdb

3.5 makefile

命名:Makefile或者makefile    --make命令
1 个规则:
  目标:依赖条件
  (TAB)命令
1. 目标的时间必须晚于依赖条件的时间
2. 依赖条件如果不存在,找寻新的规则去产生依赖条件
ALL:指定makefile的终极目标
3 个函数:
src = $(wildcard ./ *.c):匹配当前工作目录下的所有.c文件,将文件名组成列表,赋值给src
obj = $(patsubst %.c,%.o, $(src)):将参数3中包含参数1的部分替换为参数2
$(notdir $(obj)):去掉obj中的路径
clean:
  -r $(obj)  “-” 的作用是:删除不存在的文件时不报错,顺序执行结束
3 个自动变量:
   $@:在规则的命令中,表示规则中的目标
   $<:在规则的命令中,表示第一个依赖条件
   $^:在规则的命令中,表示所有依赖条件

4 文件操作

缓存区要满足一定条件才会输出:
1. \n
2. 程序结束
3. fflush()
4. 全缓存 行缓存 行缓存大小为1024
一个程序的运行需要打开三个流:
1. stdin 标准输入 --键盘
2. stdout 标准输出 --显示屏
3. stderr 标准错误 --显示屏

4.1 标准IO

(1) fopen 打开文件:
  ① 头文件:stdio.h
  ② 函数原型:FILE *fopen(const char *path, const char *mode);
  ③ 形参:path:所打开的文件路径 mode:打开模式
    “r”:只读的方式打开文件,光标在文件开头,如果文件不存在,打开失败 --只读 打开旧的文件
    “r+”:读写的方式打开文件,光标在文件开头,如果文件不存在,打开失败 --读写 打开旧的文件
    “w”:只写的方式打开文件,如果文件存在,只打开(清空写,光标在文件开头),如果文件不存在,创建并打开 --只写 以新建文件形式打开文件
    “w+”:读写的方式打开文件,如果文件存在,只打开(清空写,光标在文件开头),如果文件不存在,创建并打开 --读写 以新建文件形式打开文件
    “a”:只写的方式打开文件,如果文件存在,只打开,光标在文件末尾,追加写,如果文件不存在,创建并打开 – 追加 有旧文件就打开,没有就新建
    “a+”:读写的方式打开文件,如果文件不存在,创建并打开,如果文件存在,只打开,如果第一次对文件的操作是读,光标在文件开头,如果第一次对文件的操作是写,光标在文件末尾(追加写) --读/追加 有旧文件就打开,没有就新建
  ④ 返回值: 成功:FILE *类型的文件描述符,失败:返回NULL
(2) fclose 关闭文件:
  ① 头文件:stdio.h
  ② 函数原型:int fclose(FILE *stream);
  ③ 形参:要关闭文件的文件描述符(fopen的返回值)
  ④ 返回值: 关闭成功返回0,失败返回 -1
(3) perror 打印离他最近的函数执行失败的原因:
  ① 头文件:stdio.h
  ② 函数原型:void perror (const char *s);
  ③ 形参: s --错误标题
(4) fputc 单字符写入:
  ① 头文件:stdio.h
  ② 函数原型:int fputc (int c, FILE *stream);
  ③ 形参:
    c:填char类型的单字符
    stream:文件描述符(fopen的返回值)
  ④ 返回值: 返回写入的字符
(5) fgetc 单字符读取:
  ① 头文件:stdio.h
  ② 函数原型:int fgetc(FILE *stream);
  ③ 形参:stream --文件描述符(fopen的返回值)
  ④ 返回值:返回读取到的字符,我们需要用char类型承接
(6) rewind 使光标回到文件开头:
  ① 头文件:stdio.h
  ② 函数原型:void rewind(FILE *stream);
  ③ 形参:stream --文件描述符(fopen的返回值)
  ④ 返回值:返回读取到的字符,我们需要用char类型承接
(7) fputs 字符串的写入:
  ① 头文件:stdio.h
  ② 函数原型:int fputs(const char *s, FILE *stream);
  ③ 形参:
    s --要写入的字符串的首地址
    stream --文件描述符(fopen的返回值)
  ④ 返回值:成功 - 返回一个非负数,失败 - 返回-1
(8) fgets 字符串的读取:
  ① 头文件:stdio.h
  ② 函数原型:char *fgets(char *s, int size, FILE stream);
  ③ 形参:
    s:读取到的内容存放的地址(一般传入数组名) char a[32]; a
    size:读取多大(最大是size-1字节)
    stream文件描述符(fopen的返回值)
  ④ 返回值:成功,返回读取的字符串。不成功,返回NULL。
(9) fprintf 格式化写入:
  ① 头文件:stdio.h
  ② 函数原型:int fprintf(FILE stream,const charformat, …);
  ③ 形参:stream文件描述符(fopen的返回值)
  ④ 返回值:返回已经写入的字符数,出现错误返回EOF。
(10) fscanf 格式化读取:
  ① 头文件:stdio.h
  ② 函数原型:int fscanf(FILE
stream,const char *format, …);
  ③ 形参:stream文件描述符(fopen的返回值)
  ④ 返回值:返回可变参数中的正确获取数据的参数个数。
(11) fwrite 块写:
  ① 头文件:stdio.h
  ② 函数原型:size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
  ③ 形参:
    ptr:写入到文件中的内容的首地址
    size:一次写多大(字节)
    nmemb:写几次
    stream:fopen的返回值
  ④ 返回值:成功返回写入的字节数,失败或者到达文件结尾返回0。
(12) fread 块读:
  ① 头文件:stdio.h
  ② 函数原型:size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
  ③ 形参:
    ptr:读取到的内容存放的首地址
    size:一次读多大(字节)
    nmemb:读几次
    stream:fopen的返回值
  ④ 返回值:成功返回读出的数据块个数,失败或者到达文件结尾返回0。
(13) fseek – 光标偏移函数:
  ① 头文件:stdio.h
  ② 函数原型:int fseek(FILE *stream, long offset, int whence);
  ③ 形参:
    stream:文件描述符
    offset: 偏移量 + 往文件末尾方向偏移
            - 往文件开头方向偏移
    whence: 偏移量的起始位置 SEEK_SET 文件开头
          SEEK_CUR 当前位置
          SEEK_END 文件末尾
  ④ 返回值:成功,返回0;不成功,返回-1。
  fseek(fp,1,SEEK_CUR);//以当前位置为起始位置,往后偏移1字节
  fseek(fp,0,SEEK_SET); //等价于rewind
  fseek(fp,0,SEEK_END);//光标直接到文件末尾

//判断文件是否到达文件末尾
while(fgetc(fp) != -1)
{
	fseek(fp,-1,SEEK_CUR);
	...
}

(14) ftell – 计算光标当前位置到文件开头的偏移量
  ① 头文件:stdio.h
  ② 函数原型:long ftell(FILE *stream);
(15) feof – 判断文件是否到达文件末尾 依据上一次的读结果,判断文件是否到达文件末尾
  ① 头文件:stdio.h
  ② 函数原型:int feof(FILE *stream);
  ③ 形参:fopen的返回值
  ④ 返回值:文件结束返回非0,文件未结束返回0
    while(!feof(fp));

4.2 文件IO

(1) open 打开文件:
  ① 头文件:   #include <sys/types.h>
        #include <sys/stat.h>
        #include <fcntl.h>
  ② 函数原型: int open(const char *pathname, int flags);
         int open(const char *pathname, int flags, mode_t mode)
  ③ 形参:
    pathname:要打开的文件
    flags:打开文件的方式
      O_RDONLY:以只读的方式打开该文件
      O_WRONLY:以只写的方式打开该文件
      O_RDWR:以可读可写的方式打开该文件
      O_CREAT:如果不存在就新建,此时你就可以使用第三个参数mode,比如(0664)
      O_EXCL:如果这个文件存在就报错一般是和O_CREAT
      O_TRUNC 将文件截取为0(如果有内容就清空里边的内容)
      O_APPEND 追加的方式打开
    mode:文件的权限
  ④ 返回值: 成功返回文件描述符,失败 -1
(2) close 关闭文件:
  ① 头文件:#include <unistd.h>
  ② 函数原型:int close(int fd)
  ③ 形参:fd:open函数的返回值
  ④ 返回值: 成功返回 0 ,失败返回 -1
(3) read 从文件里读取内容到buf里:
  ① 头文件:#include <unistd.h>
  ② 函数原型:ssize_t read(int fd, void *buf, size_t count)
  ③ 形参:fd:文件描述符
       buf:存数据的缓冲区
       count:读取的大小
  ④ 返回值:0:读到文件末尾。
        成功:0 读到的字节数。失败:-1
(4) write 将buf里的内容写入到文件里:
  ① 头文件:#include <unistd.h>
  ② 函数原型:ssize_t read(int fd, void *buf, size_t count)
  ③ 形参:fd:open函数的返回值
       buf:存放读取得到内容的内存
       count:读取的大小
  ④ 返回值:成功,返回写入到文件中的数据的字节数;不成功,返回-1
(5) lseek 移动光标的位置:
  ① 头文件: #include <sys/types.h>
        #include <unistd.h>
  ② 函数原型:off_t lseek(int fd, off_t offset, int whence)
  ③ 形参:fd:open函数的返回值
       offset:偏移量,可正可负,正数往光标的右边偏,负数往光标的左边偏
       whence:SEEK_SET:文件的开头
             SEEK_CUR:当前位置
             SEEK_END:文件的末尾
  ④ 返回值:成功,返回文件开始位置到新的位置之间字节数;不成功,返回-1
(6) toupper 将小写字母转换为大写字母:
  ① 头文件:#include <ctype.h>
  ② 函数原型:int toupper(int ch);
  ③ 形参: ch:这表示要转换为大写字母的字符
  ④ 返回值:返回转化后的大写字符,$当ch不是小写字母时,返回ch.
(7) tolower 将ch转化为小写字母.:
  ① 头文件:#include <ctype.h>
  ② 函数原型:int tolower(int ch);
  ③ 形参: ch:这表示要转换为小写字母的字符
  ④ 返回值:返回转化后的小写字符,$当ch不是大写字母时,返回ch.

4.3 时间编程

与时间有关的指令:
		date          // 显示当前日期-- 中国北京时间
		date -u      //显示当前日期时间 -- 世界标准时间 UTC 
		date -R      // 显示当前日期时间 – RFC格式
		cal			 //显示日历
		cal 月 年	 //查看指定的时间
时间编程的API
	时间的核心结构体:
		struct tm {
                  int tm_sec;         /* 秒:取值区间为[0,59] */
                  int tm_min;         /* 分:取值区间为[0,59] */
                  int tm_hour;        /* 时:取值区间为[0,23] */
                  int tm_mday;        /* 日:取值区间为[1,31] */
                  int tm_mon;         /* 月:(从一月开始, 0 代表一月) :取值区间为[0,11] */
                  int tm_year;        /* 年:其值等于实际年份加上 1900*/
                  int tm_wday;        /* 星期:取值区间为[0,6],其中 0 代表星期天,1 代表星期一,以此类推 */
                  int tm_yday;    	  /* 从每年的 1 月 1 日开始的天数:取值区间为[0,365],其中 		0 代表 1 月 1 日,1 代表 1 月 2 日,以此类推*/
                  int tm_isdst;   	  /* 夏令时标识符,实行夏令时的时候,tm_isdst 为正,不实     		行夏令时的进候, tm_isdst 为 0;不了解情况时, tm_isdst()为负*/
              };

(1) time 获取日历时间:
  ① 头文件: <time.h>
  ② 函数原型: time_t time(time_t *t);
  ③ 形参:tloc:一般填写NULL
  ④ 返回值:成功返回当前的日历时间,失败返回 -1
(2) gmtime 获取格林威治时间:
  ① 头文件:<time.h>
  ② 函数原型:struct tm *gmtime(const time_t *timep);
  ③ 形参:timep:就是time函数的返回
  ④ 返回值:成功返回指向 struct tm的指针,失败返回NULL
(3) localtime 获取本地时间:
  ① 头文件:<time.h>
  ② 函数原型:struct tm *localtime(const time_t *timep);
  ③ 形参:timep:就是time函数的返回
  ④ 返回值:成功返回指向 struct tm的指针,失败返回NULL
(4) asctime 字符串形式显示时间:
  ① 头文件:<time.h>
  ② 函数原型: char *asctime(const struct tm *tm);
  ③ 形参:tm:获取本地/获取格林威治时间函数的返回值
  ④ 返回值:成功返回一个指向char类型的指针,失败NULL
(5) ctime 日历时间转本地时间:
  ① 头文件:<time.h>
  ② 函数原型: char *ctime(const time_t *timep);
  ③ 形参:timep:就是time函数的返回
  ④ 返回值:成功返回一个指向char类型的指针,失败NULL
(6) strftime 格式化显示时间:
  ① 头文件:<time.h>
  ② 函数原型: size_t strftime(char *s, size_t max, const char *format, const struct tm
  ③ 形参:s:获取得到的时间结果的一个存储位置
      max:就是s的大小
      format:就是你按照那种格式去获取时间,格式如下图
      tm:localtime或者gmtime的返回值
  ④ 返回值:成功返回获取得到的时间 失败返回 -1.
在这里插入图片描述

5 文件属性

struct stat {
	dev_t     	st_dev; /*如果是设备,返回文件使用的设备号,否则为 0*/
	ino_t       st_ino; /* 索引节点号 */
	mode_t    	st_mode; /* 文件类型 */
	nlink_t   	st_nlink; /* 文件的硬连接数 */
	uid_t    	st_uid; /* 所有者用户识别号*/
	gid_t   	st_gid; /* 组识别号 */
	dev_t   	st_rdev; /* 设备类型*/
	off_t  	 	st_size; /* 文件大小,字节表示 */
	blksize_t   st_blksize; /*  系统每次按块Io操作时块的大小(一般是512或1024)*/
	blkcnt_t   	st_blocks; /*块的索引号 */
	time_t    	st_atime; /* 最后访问时间,如read*/
	time_t    	st_mtime; /* 最后修改时间*/
	time_t    	st_ctime; /* 创建时间 */
};

1、stat 获取文件属性:
  ① 头文件: #include <sys/types.h>
        #include <sys/stat.h>
        #include <unistd.h>
  ② 函数原型:int stat(const char *pathname, struct stat *statbuf)
  ③ 形参:pathname:你提供的文件
       statbuf:文件属性的核心结构体
  ④ 返回值:成功 0 失败 -1
2、fstat 获取文件属性:
  ① 头文件: #include <sys/types.h>
        #include <sys/stat.h>
        #include <unistd.h>
  ② 函数原型:int fstat(int fd, struct stat *statbuf)
  ③ 形参:fd:文件的描述符
       statbuf:文件属性的核心结构体
  ④ 返回值:成功 0 失败 -1
stat与fstat的区别:
  stat只需要提供一个文件的路径即可,不需要打开文件
  fstat需要使用open函数打开文件,然后使用open函数返回的文件描述符来获取文件属性
3、lstat 获取文件属性:
  ① 头文件: #include <sys/types.h>
        #include <sys/stat.h>
        #include <unistd.h>
  ② 函数原型:int lstat(const char *path,struct stat *buf)
  ③ 形参:pathname:你提供的文件
       statbuf:文件属性的核心结构体
  ④ 返回值:成功 0 失败 -1
stat与lstat的区别:
  stat不能查看链接文件的属性
  lstat不仅可以查看普通文件的属性,还可以查看链接文件的属性
4、判断文件类型:
  S_ISLNK(mode) --判断是否是链接文件  l
  S_ISREG(mode) --判断是否是普通文件  -
  S_ISDIR(mode) --判断是否是目录文件  d
  S_ISCHR(mode) --判断是否是字符型设备文件  c
  S_ISBLK(mode) --判断是否是块设备文件  b
  S_ISFIFO(mode) --判断是否是管道文件  p
  S_ISSOCK(mode) --判断是否是套接字文件  s
5、access 判断文件是否存在,以及文件的各个权限是否存在:
  ① 头文件: #include <unistd.h>
  ② 函数原型:int access(const char *pathname, int mode)
  ③ 形参:pathname:你要判断的文件
       mode:你要判断什么
          R_OK:读权限
          W_OK:写权限
          X_OK:执行权限
          F_OK:文件是否存在
  ④ 返回值:成功 0 失败 -1

6 目录操作

1、mkdir 创建目录:
  ① 头文件: #include <sys/stat.h>
        #include <sys/types.h>
  ② 函数原型:int mkdir(const char *pathname, mode_t mode)
  ③ 形参:pathname:你要创建的目录名
       mode:创建目录的时候给他指定的权限
          权限这里要注意给的权限里要包含x执行权限
  ④ 返回值:成功 0 失败 -1
        mkdir(argv[1], 0664);
2、rmdir 删除目录:
  ① 头文件:#include <unistd.h>
  ② 函数原型:int rmdir(const char *pathname)
  ③ 形参:pathname:你要删除的目录名
  ④ 返回值:成功 0 失败 -1
        rmdir(argv[1]);
3、getcwd 查看当前路径:
  ① 头文件:#include <unistd.h>
  ② 函数原型:char *getcwd(char *buf, size_t size)
  ③ 形参:buf:存储获取得到的路径
       size:buf的大小,最大是255
  ④ 返回值:成功返回指向 char类型的地址,失败NULL
      char *p = getcwd(buf, sizeof(buf));
4、chdir 切换指定的路径:
  ① 头文件:#include <unistd.h>
  ② 函数原型:int chdir(const char *path)
  ③ 形参:path:你要切换的路径
  ④ 返回值:成功 0 失败 -1
      chdir(“/home/zyl/test/C”);
5、chmod 给指定的文件修改权限:
  ① 头文件:#include <sys/stat.h>
  ② 函数原型:int chmod(const char *pathname, mode_t mode)
  ③ 形参:pathname:目录名
       mode:权限 使用八进制表示
  ④ 返回值:成功 0 失败 -1
      chmod(argv[1], 0555);
6、system 执行系统的命令函数:
  ① 头文件:#include <stdlib.h>
  ② 函数原型:int system(const char *command)
  ③ 形参:command:你要执行的命令
  ④ 返回值:成功 0 失败 -1

目录操作的结构体:
存储目录中的文件信息(文件名、扩展名等等)
#include <dirent.h>
struct dirent
{
   	 long d_ino; /* inode number 索引节点号 */
   	 off_t d_off; /* offset to this dirent 在目录文件中的偏移 */
     unsigned short d_reclen; /* length of this d_name 文件名长 */
 	 unsigned char d_type; /* the type of d_name 文件类型 */
 	 char d_name [NAME_MAX+1]; /* file name (null-terminated) 文件名,最长255字符 */
}
d_tyep 有 8 种类型:
      (1)、 DT_BLK      This is a block device.           块设备
      (2)、 DT_CHR      This is a character device.       字符设备
      (3)、 DT_DIR       This is a directory.              目录 
      (4)、 DT_FIFO     This is a named pipe (FIFO).      管道
      (5)、 DT_LNK      This is a symbolic link.          软链接
      (6)、 DT_REG      This is a regular file.           普通文件
      (7)、 DT_SOCK     This is a UNIX domain socket.     套接字
      (8)、 DT_UNKNOWN     The file type is unknown.         未知类型   

7、opendir 打开指定的目录:
  ① 头文件:#include <sys/types.h>
        #include <dirent.h>
  ② 函数原型:DIR *opendir(const char *name)
  ③ 形参:name:你要打开的目录
  ④ 返回值:成功返回一个指向DIR指针,失败NULL
      DIR *dir = opendir(argv[1]);
8、closedir 关闭打开的目录:
  ① 头文件:#include <sys/types.h>
        #include <dirent.h>
  ② 函数原型:int closedir(DIR *dirp)
  ③ 形参:dirp:opendir函数返回值
  ④ 返回值:成功返回 0 失败返回-1.
      closedir(dir);
9、readdir 读取目录里的内容:
  ① 头文件:#include <dirent.h>
  ② 函数原型:struct dirent *readdir(DIR *dirp)
  ③ 形参:dirp:opendir函数返回值
  ④ 返回值:成功返回指向struct dirent指针,失败NULL
      struct dirent *p = NULL;
      p = readdir(dir)
10、strstr 在你指定的字符串里查找你指定的字符串第一次出现的位置:
  ① 头文件:#include <string.h>
  ② 函数原型:char *strstr(const char *haystack, const char *needle)
  ③ 形参:haystack:你要查找的源字符串
       needle:你指定查找的字符串
  ④ 返回值:成功就返回查找到的指向字符串的指针,失败NULL
11、rewinddir 将目录里的目录流拉到开头:
  ① 头文件:#include <sys/types.h>
        #include <dirent.h>
  ② 函数原型:void rewinddir(DIR *dir);
  ③ 形参:dirp:opendir函数返回值
  ④ 返回值:无
      rewinddir(dir);
12、seekdir 把目录流移动到你指定的位置:
  ① 头文件:#include <dirent.h>
  ② 函数原型:void seekdir(DIR *dir,off_t offset);
  ③ 形参:dirp:opendir函数返回值
       offset:你要移动的位置,这里需要使用获取目录流位置的函数
  ④ 返回值:无
      seekdir(dir, offset);
13、telldir 获取当前目录流的位置:
  ① 头文件:#include <dirent.h>
  ② 函数原型:off_t telldir(DIR *dir);
  ③ 形参:dirp:opendir函数返回值
  ④ 返回值:成功返回目录流的下一个位置,失败返回 -1.
      offset = telldir(dir);

7 进程

1、fork 创建新进程:
  ① 头文件:<unistd.h>
  ② 函数原型:pid_t fork(void)
  ③ 返回值:父子进程各自返回,父进程返回子进程的PID,子进程返回0
2、vfork 创建新进程:
  ① 头文件:<unistd.h>
  ② 函数原型:pid_t vfork(void)
  ③ 返回值:在父进程中成功返回子进程的PID,在子进程中返回的PID是0,出错 -1.
  特点:
  一但子进程创建成功会先运行子进程,并且子进程运行结束,父进程才会执行,,也就是说子进程会阻塞父进程,资源是共享的
  子进程退出的时候需要使用 exit(0)
3、getpid 获取子进程的PID:
  ① 头文件: #include <sys/types.h>
        #include <unistd.h>
  ② 函数原型:pid _t getpid(void)
  ③ 返回值:调用该函数的进程id
4、getppid 获取父进程的PID:
  ① 头文件: #include <sys/types.h>
  #include <unistd.h>
  ② 函数原型:pid_t getppid(void)
  ③ 返回值:调用该函数的进程的父进程id
5、exec函数族
  将当前函数的.text和.data替换为要加载的程序的.text和.data,然后让进程从新的.text第一条指令开始运行,但进程ID不变,换核不换壳
6.execl 在一个进程中执行其他进程:
  ① 头文件:#include <unistd.h>
  ② 函数原型:int execl(const char *pathname, const char arg, … / (char *) NULL */)
  ③ 形参:pathname:要执行文件的路径,最好是绝对路径,如果不写默认去当前路径找
  ④ 返回值:成功返回0,失败返回 -1.
7. execlp 在一个进程中执行其他进程:
  ① 头文件:#include <unistd.h>
  ② 函数原型: int execlp(const char *file, const char arg, …/ (char *) NULL */)
  ③ 形参:file:要执行的文件,如果没有写路径回去系统默认环境变量上去找
       arg:执行这个进程所需要的指令
          最后一个参数必须要使用NULL
  ④ 返回值:成功返回0,失败返回 -1.
8、特殊进程
  孤儿进程
    父进程先于子进程终止,子进程沦为孤儿进程,会被init进程收养
  僵尸进程
    子进程终止,父进程尚未对子进程进程回收,再次期间,子进程为僵尸进程。 kill对僵尸进程无效
9、wait 回收子进程退出资源:
  ① 头文件:#include <sys/types.h>
        #include <sys/wait.h>
  ② 函数原型:pid_t wait(int *wstatus)
  ③ 形参: wstatus:一般填写NULL
  ④ 返回值:① 如果成功,wait会返回被收集的子进程的进程ID;
        ② 如果调用进程没有子进程,调用就会失败,此时wait返回-1
10、waitpid 回收子进程退出资源:
  ① 头文件:#include <sys/types.h>
        #include <sys/wait.h>
  ② 函数原型:pid_t waitpid(pid_t pid, int *wstatus, int options)
  ③ 形参:pid:要回收的那个进程的pid
       wstatus:一般填写NULL
       options:0:同 wait,阻塞父进程,等待子进程退出 waitpid(pid,NULL,0) == wait
          WNOHANG:指定回收方式为,非阻塞。
  ④ 返回值:   ① 当正常返回的时候,waitpid返回收集到的子进程的进程ID;
        ② 如果设置了选项WNOHANG,而调用中waitpid发现没有已退出的子进程可收集,则返回0;      
        ③ 如果调用中出错,则返回-1
11、shell命令:
    ① kill -9 进程号 杀死进程
    ② ps -aux 查看进程的详细信息
  stat:
    S:睡眠
    R:运行
      执行或即将运行状态
    D:不可中断的睡眠(等待)
      通常等待输入或输出的完成
    T:停止
      通常是被shell或调试器控制停止
    N:低优先级任务
    Z:僵尸进程
    X:死进程
    s:进程是会话期首进程
    +:后台进程
      和用户交互的任务
    l:进程是多线程的
    <:高优先级任务

8 信号

1、特殊信号:
  信号2:ctrl+c
  信号3:ctrl+
  信号9:杀死一个进程
  信号19:暂停信号
  信号18:继续信号
  信号14:SIGALRM:闹钟信号,用于定时
  信号17:用于父子之间的信号
    产生17信号的方式有三种:
    (1)子进程结束
    (2)遇到19信号
    (3)遇到18信号
2、signal 注册一个捕获信号:
  ① 头文件:#include <signal.h>
  ② 函数原型:sighandler_t signal(int signum, sighandler_t handler)
  ③ 形参:signum:要捕获的信号
       handler:三种方式
          ① 默认处理
          ② 忽略(不能忽略的信号:SIGKILL,SIGSTOP)
          ③ 自定义typedef void (*sighandler_t)(int)
  ④ 返回值:成功返回捕获到的信号,失败 errno
3、kill 发送信号:
  ① 头文件:#include <sys/types.h>
        #include <signal.h>
  ② 函数原型:int kill(pid_t pid, int sig)
  ③ 形参:pid:要给哪个进程发送信号
       sig:发送什么信号
  ④ 返回值:成功返回 0 失败 -1
4、raise 给本进程发送信号:
  ① 头文件:#include <sys/types.h>
        #include <signal.h>
  ② 函数原型:int raise(int sig);
  ③ 形参:sig:发送什么信号
  ④ 返回值:成功返回 0 失败 -1.
5、alarm 设置时间值,到达时间产生SIGALRM–14 信号,不捕捉的时候默认终止进程(给进程本身发送):
① 头文件:#include<unistd.h>
② 函数原型:unsigned int alarm(unsigned int seconds)
③ 形参:seconds:你设置产生闹钟信号的时间 单位是秒
④ 返回值:如果调用此alarm()前,进程已经设置了闹钟时间,则返回上一个闹钟时间的剩余时间,否则返回0。
6、pause 阻塞当前的进程,直到产生一个信号才会解除阻塞:
  ① 头文件:#include<unistd.h>
  ② 函数原型:int pause(void);
  ③ 返回值:成功 0 失败 -1.
7、glob 在你指定的路径下,查找你指定的文件:
  ① 头文件:#include <unistd.h>
  ② 函数原型:int glob(const char *pattern, int flags,int (*errfunc) (const char *epath, int eerrno),glob_t *pglob)
  ③ 形参:pattern:你要查找的路径
       flags:0
       errfunc:NULL
       pglob:他就是你找到结果保存的一个位置

typedef struct
{
  __size_t gl_pathc; /* 指定文件匹配的数量 */
  char *gl_pathv; / 指定匹配文件的文件名 */
} glob_t;

  ④ 返回值:成功返回 0 失败 -1.

9 管道

1、pipe 创建无名管道:
  ① 头文件:#include <unistd.h>
  ② 函数原型:int pipe(int pipefd[2])
  ③ 形参:pipefd:管道的两个端 fd[0] – 读端 fd[1] – 写端
  ④ 返回值:成功返回 0 失败 -1.
    注意:管道创建成功后,就处于打开的状态,父子进程使用无名管道进行通信的时候,子进程一定是在管道创建成功之后才创建的
2、mkfifo 创建有名管道:
  ① 头文件:#include <sys/types.h>
        #include <sys/stat.h>
  ② 函数原型:int mkfifo(const char *pathname, mode_t mode)
  ③ 形参:pathname:管道的名字
       mode:创建管道的时候给他指定的权限
  ④ 返回值:成功返回 0 失败 -1.
  注意:管道创建成功之后必须先使用open函数打开
3、unlink 删除有名管道/删除指定路径的文件:
  ① 头文件:#include <unistd.h>
  ② 函数原型:int unlink(const char *pathname)
  ③ 形参:pathname:删除的文件名
  ④ 返回值:成功返回 0 失败 -1.

10 共享内存

1、shmget 创建/获取共享内存:
  ① 头文件:#include <sys/ipc.h>
        #include <sys/shm.h>
  ② 函数原型:int shmget(key_t key, size_t size, int shmflg)
  ③ 形参:key:键值
       size:共享内存的大小
       shmflg:你进行的操作
          IPC_CREAT:没有就创建一般要|权限
          IPC_CREAT|0666
  ④ 返回值:成功返回共享内存的id,失败-1.
2、shmat 共享内存映射:
  ① 头文件:#include <sys/types.h>
       #include <sys/shm.h>
  ② 函数原型:void *shmat(int shmid, const void *shmaddr, int shmflg)
  ③ 形参:shmid:共享内存的id
       shmaddr:你要把共享内存的地址保存到哪里,这里一般写NULL,系统会对当前的进程里分配一块可以的空间,供共享内存使用。
       shmflg: 默认 0:共享内存可读写
       SHM_RDONLY:共享内存只读
  ④ 返回值:成功返回一个地址,这个地址就是你对共享内存操作的地址,失败NULL
3、ftok 创建键值:
  ① 头文件:#include <sys/types.h>
        #include <sys/ipc.h>
  ② 函数原型:key_t ftok(const char *pathname, int proj_id)
  ③ 形参:pathname:提供的文件
       proj_id:子序列号,取值范围是 0 – 255
  ④ 返回值:成功返回创建的键值,失败 -1.
4、shmctl 对共享内存进行设置:
  ① 头文件:#include <sys/ipc.h>
        #include <sys/shm.h>
  ② 函数原型:int shmctl(int shmid, int cmd, struct shmid_ds *buf)
  ③ 形参:shmid:共享内存的id
       cmd:你要对共享内存进行什么操作
          IPC_RMID:删除共享内存,此时第三个参数直接写NULL
          IPC_STAT:获取共享内存属性,那么此时你就要填写第三个参数
          IPC_SET:修改共享内存
buf:保存获取得到的共享内存的信息
  ④ 返回值:成功返回是第二个参数的不同返回的也不同,失败 -1.
5、memcpy 把指定的内容拷贝到指定的地址空间中:
  ① 头文件:#include <string.h>
  ② 函数原型:void *memcpy(void *dest, const void *src, size_t n)
  ③ 形参:dest:拷贝的地址空间
       src:你要拷贝的内存
       n:拷贝内容的大小
  ④ 返回值:成功返回指向void类型的一个地址,失败NULL

11 信号量集

1、semget 创建/获取信号量集:
  ① 头文件:#include <sys/types.h>
        #include <sys/ipc.h>
        #include <sys/sem.h>
  ② 函数原型:int semget(key_t key, int nsems, int semflg)
  ③ 形参:key:键值
       nsems:信号量集的数量,这里一般填写 1
       semflg:你要进行的操作
          IPC_CREAT:创建|权限
          IPC_CREAT|0666
  ④ 返回值:成功返回信息量的id 失败 -1.
2、semctl 信号量集设置:
  ① 头文件:#include <sys/types.h>
        #include <sys/ipc.h>
        #include <sys/sem.h>
  ② 函数原型:int semctl(int semid, int semnum, int cmd, …)
  ③ 形参:semid:信号量id
       semnum:信号量的下标,这里是一个集合,而集合的下标是从0开始的,0就代表你信号量集里的第一个信号量。一般填写0
       cmd:你要对信号量进行什么操作
          IPC_RMID:删除信号量,此时他就是最后一个参数
          SETVAL:他是对咱们的信号量进行设置初值,此时你要填写第四个参数。

 union semun {
			int              val;    /* Value for SETVAL */
		   struct semid_ds *buf;    /* Buffer for IPC_STAT, IPC_SET */
		   unsigned short  *array;  /* Array for GETALL, SETALL */
		   struct seminfo  *__buf;  /* Buffer for IPC_INFO(Linux-specific) */
		 };

          GETVAL:获取当前的信量的值,此时不需要填写第四个参数,而这个函数的返回值就是当前信号量的值。
  ④ 返回值:成功返回 跟进第三个参数的不同而不同,失败 -1.
3、semop 对信号量集进行P/V操作 (P为-1, V为+1 ):
  ① 头文件:#include <sys/types.h>
        #include <sys/ipc.h>
        #include <sys/sem.h>
  ② 函数原型:int semop(int semid, struct sembuf *sops, size_t nsops)
  ③ 形参:semid:信号量的id
       sops:操作的核心结构体

 unsigned short sem_num;  /* semaphore number */
 short          sem_op;   /* semaphore operation */
 short          sem_flg;  /* operation flags */
 sem_num:一般填写 0 
 sem_op:就是你要进行p/v  -1/p   1/v
 sem_flg: 一般是写SEM_UNDO

信号量的SEM_UNDO标志是用于在进程终止时自动撤销对信号量的操作。当一个进程对信号量进行P操作(减少信号量值)或V操作(增加信号量值)时,如果设置了SEM_UNDO标志,那么在进程终止时,操作系统会自动将进程对信号量的操作撤销,即恢复信号量的值。这个标志的作用是为了防止进程异常终止导致信号量的值不一致。如果一个进程在对信号量进行P操作后异常终止,而没有撤销对信号量的操作,那么其他进程可能会一直等待该信号量的值恢复,从而导致死锁。通过设置SEM_UNDO标志,操作系统可以在进程终止时自动撤销对信号量的操作,避免这种情况的发生。

       nsops:一般是1
  ④ 返回值:成功返回 0 失败 -1.

12 消息队列

msgp:指向消息结构的指针。该消息结构 msgbuf 为:

struct msgbuf{
	long mtype;//消息类型
	char mtext[1];//消息正文
}

1、msgget 创建/获取消息队列:
  ① 头文件:#include <sys/types.h>
        #include <sys/ipc.h>
        #include <sys/msg.h>
  ② 函数原型:int msgget(key_t key, int msgflg)
  ③ 形参:key:键值
       msgflg:你要对他进行什么操作
          IPC_CREAT:创建
          IPC_CREAT|0666
  ④ 返回值:成功返回 消息队列的Id 失败 -1.
2、msgsnd 发送消息到消息队列:
  ① 头文件:#include <sys/types.h>
        #include <sys/ipc.h>
        #include <sys/msg.h>
  ② 函数原型:int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg)
  ③ 形参:msqid:消息队列的Id
       msgp:你发送消息的结构体
       msgsz:发送消息正文的大小
       msgflg:0 没有满足我就阻塞
  ④ 返回值:成功返回 0 失败 -1.
3、msgrcv 从消息队列中接收指定消息类型的消息:
  ① 头文件:#include <sys/types.h>
        #include <sys/ipc.h>
        #include <sys/msg.h>
  ② 函数原型:ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg)
  ③ 形参:msqid:消息队列的Id
       msgp:你发送消息的结构体
       msgsz:发送消息正文的大小
       msgtyp:消息类型
       msgflg:0 阻塞
  ④ 返回值:成功返回 0 失败 -1.
4、msgctl 对消息队列进行设置:
  ① 头文件:#include <sys/types.h>
        #include <sys/ipc.h>
        #include <sys/msg.h>
  ② 函数原型:int msgctl(int msqid, int cmd, struct msqid_ds *buf)
  ③ 形参:msqid:消息队列的Id
       cmd:
        IPC_STAT:读取消息队列的数据结构 msqid_ds,并将其存储在buf 指 定的地址中
        IPC_SET:设置消息队列的数据结构 msqid_ds 中的 ipc_perm 元素的值。这个值取自 buf 参数
        IPC_RMID:从系统内核中移走消息队列,第三个参数直接给NULL
  ④ 返回值:成功返回 0 失败 -1.

ipcrm -m xxxid号   删除指定的共享内存
ipcrm -q xxxid号   删除指定的消息队列 ipcrm -s
xxxid号   删除指定的信号量

13 多线程

运行线程需要添加库:gcc xxx.c -o xxx -lpthread
1、pthread_create 创建一个线程:
  ① 头文件:#include <pthread.h>
  ② 函数原型:int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg)
  ③ 形参:thread:保存线程的ID
       attr:直接写NULL
       start_routine:线程的入口函数,他也就是你所创建的线程
       arg:你给线程函数传递的参数,根据自己的需求去填充
  ④ 返回值:成功 0, 失败 -1。
2、pthread_join 等待指定的线程退出:
  ① 头文件:#include <pthread.h>
  ② 函数原型:int pthread_join(pthread_t thread, void **value_ptr);
  ③ 形参:thread:你要等待的线程的id
       value_ptr:直接写NULL
  ④ 返回值:成功 0, 失败 -1。
3、pthread_exit 线程的正常退出:
  ① 头文件:#include <pthread.h>
  ② 函数原型:void pthread_exit(void *retval)
  ③ 形参:retval:一般填的0
  ④ 返回值:无
4、pthread_cancel 取消一个正在运行的线程:
  ① 头文件:#include <pthread.h>
  ② 函数原型:int pthread_cancel(pthread_t thread);
  ③ 形参:thread:你要取消线程的id
  ④ 返回值:成功返回 0 失败 -1.

线程控制原语      进程控制原语
pthread_create()      fork();
pthread_self()       getpid();
pthread_exit()      exit(); / return
pthread_join()      wait()/waitpid()
pthread_cancel()      kill()
pthread_detach()

5、线程清理函数,在线程退出的时候执行他去清理一些资源:
  ① 头文件:#include <pthread.h>
  ② 函数原型:void pthread_cleanup_pop(int execute);//决定是否执行清理函数
         void pthread_cleanup_push(void (routine)(void), void *arg);//注册清理函数
  两个函数必须配对使用,并且注册的函数遵循栈的规则,即先进后出,先注册的就后执行
  ③ 形参:execute:他是决定你是否要执行注册函数的关键 0 就是不执行的
            非零就执行你注册的函数
       routine:你要注册的清理函数
       arg:给注册清理函数传递的参数
  ④ 返回值:无
线程清理函数执行的条件有三个:
  1. pthread_cleanup_pop(1)
  2. 线程还未执行 pthread_cleanup_pop 前,主动执行 pthread_exit 终止
  3. 线程还未执行 pthread_cleanup_pop 前,主动执行 pthread_ cancel 终止
6、pthread_kill 给指定的线程发送指定的信号:
  ① 头文件:#include <signal.h>
  ② 函数原型:int pthread_kill(pthread_t thread, int sig)
  ③ 形参:thread:线程的id号
       sig:你要发送什么信号
  ④ 返回值:成功返回 0 失败 -1.

14 线程同步

使用mutex(互斥量、互斥锁)一般步骤:
pthread_mutex_t 类型。
  1. pthread_mutex_t lock; 创建锁
  2 pthread_mutex_init; 初始化 1
  3. pthread_mutex_lock;加锁 1----> 0
  4. 访问共享数据(stdout)
  5. pthrad_mutext_unlock();解锁 0++ --> 1
  6. pthead_mutex_destroy;销毁锁
初始化互斥量:
pthread_mutex_t mutex;
  1. pthread_mutex_init(&mutex, NULL); 动态初始化。
  2. pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 静态初始化。

注意事项: 尽量保证锁的粒度, 越小越好。(访问共享数据前,加锁。访问结束【立即】解锁。)
互斥锁,本质是结构体。我们可以看成整数。 初值为 1。(pthread_mutex_init() 函数调用成功。)
加锁: --操作, 阻塞线程。
解锁:++操作, 换醒阻塞在锁上的线程。
try锁:尝试加锁,成功–。失败,返回。同时设置错误号 EBUSY

1、 pthread_mutex_init 初始化互斥锁:
  ① 头文件:#include <pthread.h>
  ② 函数原型:int pthread_mutex_init(pthread_mutex_t *mutex, pthread_mutexattr_t *attr)
  ③ 形参:mutex:你定义的互斥锁
       attr:写NULL
  ④ 返回值:成功 0, 失败 -1。
2、 pthread_mutex_lock 加锁:
  ① 头文件:#include <pthread.h>
  ② 函数原型:int pthread_mutex_lock(pthread_mutex_t *mutex);
  ③ 形参:mutex:你顶定义的互斥锁
  ④ 返回值:成功 0, 失败 -1。
  如果此锁正在被别的线程使用,那么就会造成当前的线程阻塞,一直等待另一个线程把锁给释放。
3、 pthread_mutex_trylock 尝试获取互斥锁:
  ① 头文件:#include <pthread.h>
  ② 函数原型:int pthread_mutex_trylock(pthread_mutex_t *mutex);
  ③ 形参:mutex:你顶定义的互斥锁
  ④ 返回值:成功 0, 失败 -1。
  如果此锁正在被别的线程使用,那么就会立即返回接着往下运行不会造成线程阻塞。
4、 pthread_mutex_unlock 解锁:
  ① 头文件:#include <pthread.h>
  ② 函数原型:int pthread_mutex_unlock(pthread_mutex_t *mutex);
  ③ 形参:mutex:你顶定义的互斥锁
  ④ 返回值:成功 0, 失败 -1。
5、 pthead_mutex_destroy 销毁锁:
  ① 头文件:#include <pthread.h>
  ② 函数原型:int pthread_mutex_destroy(pthread_mutex_t *mutex);
  ③ 形参:mutex:你顶定义的互斥锁
  ④ 返回值:成功 0, 失败 -1。

15 条件变量

在没有满足条件的时候就阻塞等待,等满足条件后就解除阻塞,条件变量和互斥锁联合使用
1、 pthread_cond_init 创建一个条件变量:
  ① 头文件:#include <pthread.h>
  ② 函数原型:int pthread_cond_init(pthread_cond_t *restrict cond,const pthread_condattr_t *restrict attr);
  ③ 形参:cond:你定义的条件变量
       attr:写NULL
  ④ 返回值:成功 0, 失败 -1。
2、 pthread_cond_wait 条件不满足就阻塞等待:
  ① 头文件:#include <pthread.h>
  ② 函数原型:int pthread_cond_wait(pthread_cond_t *restrict cond,pthread_mutex_t *restrict mutex);
  ③ 形参:cond:你定义的条件变量
       mutex:你定义的互斥锁
  ④ 返回值:成功 0, 失败 -1。
3、 pthread_cond_signal 解除阻塞:
  ① 头文件:#include <pthread.h>
  ② 函数原型: int pthread_cond_signal(pthread_cond_t *cond);
  ③ 形参:cond:你定义的条件变量
  ④ 返回值:成功 0, 失败 -1。
4、 pthread_cond_destroy 销毁条件变量:
  ① 头文件:#include <pthread.h>
  ② 函数原型:int pthread_cond_destroy(pthread_cond_t *cond);
  ③ 形参:cond:你定义的条件变量
  ④ 返回值:成功 0, 失败 -1。

16 信号量

1、 sem_init 创建一个信号量:
  ① 头文件:#include <semaphore.h>
  ② 函数原型:int sem_init(sem_t *sem, int pshared, unsigned int value)
  ③ 形参:sem:定义的信号量
       pshared:填写 0
       value:信号量的初值 一般是 1
  ④ 返回值:成功 0, 失败 -1。
2、 sem_getvalue 获取当前信号量的值:
  ① 头文件: #include <semaphore.h>
  ② 函数原型: int sem_getvalue(sem_t *sem, int *sval);
  ③ 形参:sem: 定义的信号量
       sval:信号量的值
  ④ 返回值:成功 0, 失败 -1。
3、 sem_wait 改变信号量的值(-1):
  ① 头文件:#include <semaphore.h>
  ② 函数原型:int sem_wait(sem_t *sem);
  ③ 形参:sem: 定义的信号量
  ④ 返回值:成功 0, 失败 -1。
4、 sem_post 改变信号量的值(+1):
  ① 头文件:#include <semaphore.h>
  ② 函数原型:int sem_post(sem_t *sem);
  ③ 形参:sem: 定义的信号量
  ④ 返回值:成功 0, 失败 -1。
5、 sem_destroy 销毁信号量:
  ① 头文件:#include <semaphore.h>
  ② 函数原型:int sem_destroy(sem_t *sem);
  ③ 形参:sem: 定义的信号量
  ④ 返回值:成功 0, 失败 -1。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值