Linux中级开发命令、编程工具make,系统调用、内核及进程、管道的使用方法

第七章 Linux下编程工具

7.1 make概述

GNU make是一种代码维护工具。

make工具会根据makefile文件定义的规则和步骤,完成整个软件项目的代码维护工作。

一般用来简化编译 工作,可以极大地提高软件开发的效率。
windows’下一般由集成开发环境自动生成;

linux下需要由我们按照其语法自己编写。
Make主要解决两个问题:

  1. 大量代码的关系维护
    ➢大项目中源代码比较多,手工维护、编译时间长而且编译命令复杂,难以记忆及维护把代码
    维护命令及编译命令写在makefile文件中,然后再用make.工具解析此文件自动执行相应命令,
    可实现代码的合理编译
    2.减少重复编译时间
    ➢在改动其中-个文件的时候,能判断哪些文件被修改过,可以只对该文件进行重新编译,然
    后重新链接所有的目标文件,节省编译时间

7.2 make命令格式

make命令格式

make [ -f file] [ options ] [ targets ]
  1. [-f file]: make默认在工作目录中寻找名为GUNmakefile、 makefile、Makefile的文件作为
    makefile输入文件-f可以指定以上名字以外的文件作为makefile输入文件;
  2. [ options ]执行参数:辅助makefile执行, 我们最后介绍;
  3. [ targets ]:若使用make命令时没有指定目标, 则make. 工具默认会实现makefile文件内的
  4. 第一个目标,然后退出指定了make. I具要实现的目标,目标可以是一个或多个(多个目标
    间用空格隔开)。

7.3 makefile语法

目标:依赖文件列表
<Tab>命令列表

目标通常是要产生的文件名称, 目标可以是可执行文件或其它obj文件,也可是一个动作的名称;

依赖文件:是用来输入从而产生目标的文件-个目标通常有几个依赖文件(可以没有) ;

命令: make执行的动作,一 个规则可以含几个命令(可以没有)有多个命令时, 每个命令占- -行。
在这里插入图片描述

7.4 makefile变量

makefile变量类似于C语言中的宏,当makefile 被make.工具解析时,其中的变量会被展开。

变量的作用:
➢保存文件名列表
➢保存文件目录列表
➢保存编译器名
➢保存编译参数
➢保存编译的输出

7.4.1makefile变量的分类

◆自定义变量

➢在makefile文件中定义的变量。
➢make工具传给makefile的变量。
◆系统环境变量
➢make. 工具解析makefile前,读取系统环境变量并设置为makefile的变量。
◆预定义变量(自动变量)

7.4.2makefile自定义变量语法

定义变量:变量名=变量值

引用变量: ( 变 量 名 ) 或 (变量名)或 (){变量名}

◆makefile的变量名:

makefile变量名可以以数字开头
◆变量是大小写敏感的;

◆变量一般都在makefile的头部定义;
◆变量几乎可在makefile的任何地方使用。

make_ I具传给makefile的变量

执行make命令时,make的参数options也可以给makefile设置变量。

◆系统环境变量
make_ I具会拷贝系统的环境变量并将其设置为makefile的变量,在makefile中可直接读取
或修改拷贝后的变量。
在这里插入图片描述

7.4.3 makefile预定义变量

makefile中有许多预定义变量,这些变量具有特殊的含义,可在makefile中直接使用。

$@目标名
$* 目标名中除含扩展名的部分扩展名包括: S、s、C、 C、CC、cp、 cpp、 o、a等
 $<依赖文件列表中的第一 个文件
 $^依赖文件列表中除去重复文件的部分
 $+ 依赖文件列表中所有的文件
$? 依赖文件列表中比目标文件新的文件
AR归档维护程序的程序名,默认值为ar
ARFLAGS归档维护程序的选项
AS汇编程序的名称,默认值为as
ASFLAGS汇编程序的选项
CC C编译器的名称,默认值为cc
CFLAGS C编译器的选项
CPP C预编译器的名称,默认值为$(CC) -E
CPPFLAGS C预编译的选项
CXX C+ +编译器的名称,默认值为g+ +
CXXFLAGS C+ +编译器的选项

在这里插入图片描述

[ options ]的含义:
-V:显示make.工具的版本信息
-w:在处理makefile之前和之后显示工作路径
-C dir:读取makefile之前改变工作路径至dir目录
-n:只打印要执行的命令但不执行
-s:执行但不显示执行的命令

第八章 系统调用与系统IO

8.1系统调用与内核

在这里插入图片描述
系统调用是操作系统提供给用户程序的一组"特殊” 接口。
Linux的不同版本提供了两百个系统调用。
用户程序可以通过这组接口获得操作系统(内核)提供的服务。

例如:用户可以通过文件系统相关的系统调用,请求系统打开文件、关闭文件或读写文件。
在这里插入图片描述
◆系统调用按照功能逻辑大致可分为:进程控制、进程间通信、文件系统控制、系统控制、
内存管理、网络管理、socket控制、 用户管理。
◆系统调用通常通过函数进行调用。
系统调用的返回值:
通常,用一个负的返回值来表明错误,返回一个0值表明成功。错误信息存放在全局变量errno中,用户可用perror函数打印出错信息。
系统调用遵循的规范

在Linux中,应用程序编程接口(API)遵循POSIX标准。
POSIX标准描述了操作系统的函数接口规范(函数名、返回值、参数等)。
不同操作系统下编写的程序只要遵循POSIX标准,程序都可以直接移植。
如: linux’ 下写的open、write 、read可以直接移植到unix操作系统下。

8.2 系统调用函数

◆系统调用中操作I/O的函数,都是针对文件描述符的。通过文件描述符可以直接对相应的
文件进行操作。如: open、close、 write 、read. ioctl 0

8.2.1文件描述符

文件描述符是非负整数。打开现存文件或新建文件时,系统(内核)会返回一个文件描述符。文件描述符用来指定已打开的文件。

#define STDIN_ _FILENO 0 //标准输入的文件描述符
#define STDOUT_ _FILENO 1 //标准输出的文件描述符
#define STDERR_ _FILENO 2 //标准错误的文件描述符

◆程序运行起来后这三个文件描述符是默认打开的。

8.2.2open函数

:打开-个文件

#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);

8.2.3 open函数

打开一个文件
◆参数:

pathname: 文件的路径及文件名。
flags: open函数的行为标志。
mode: 文件权限(可读、可写、可执行)的设置。

◆返回值:

➢成功返回打开的文件描述符。
➢失败返回-1,可以利用perror去查看原因。
在这里插入图片描述
在这里插入图片描述

8.2.4 close函数

: 关闭一个文件

#include <unistd.h>
int close(int fd);
参数: fd是调用open打开文件返回的文件描述符

返回值:
➢成功返回0。
➢失败返回-1,可以利用perror去查看原因。

8.2.5 write函数

:把指定数目的数据写到文件

#include <unistd.h>
ssize_ t write(int fd, const void *addr, size_ _t count);
参数:
➢fd: 文件描述符。
➢addr: 数据首地址。
➢count: 写入数据的字节个数。

返回值:
➢成功返回实际写入数据的字节个数。
➢失败返回-1,可以利用perror去查看原因。

8.2.6read函数

:把指定数目的数据读到内存

#include <unistd.h>
ssize_ t read(int fd, void *addr, size_ _t count);
参数:
➢fd: 文件描述符。
➢
addr:内存首地址。
count:读取的字节个数。

返回值:
➢成功返回实际读取到的字节个数。
➢失败返回-1, 可以利用perror去查看原因。

8.3 系统调用与内核

为了更好地保护了内核,在Linux中,把程序运行空间分为内核空间和用户空间,它们分别运行在不同的级别上。
用户进程在通常情况下不允许访问内核数据,也无法使用内核函数。
但在有些情况下,用户空间的进程需要获得一定的系统服务,这时,就必须通过系统调用。
在这里插入图片描述

1.应用程序运行在用户空间,系统调用需要切换到内核空间,应用程序应该以某种方式通知内核需要切换到内核空间。
通知内核的机制是靠软件中断实现的:

应用程序执行异常指令,引发一个异常, 程序进入中断,系统切换到内核态去执行异常处理程序。此处的异常处理程序即系统调用处理程序 syscall().

所有的系统调用陷入内核的方式都一样,所以仅仅是陷入内核空间是不够的。必须以某种方式通知内核进入异常的原因。
Unix系统通过系统调用号通知内核进入异常的原因。

系统调用号操作系统给每个系统调用分配了一个唯一的编号,这个编号就是系统调号。用户空间

进程执行一个系统调用时,这个系统调用号就被用来指明执行哪个系统用。
系统调用号相当关键,- -旦分配就不能再有任何变更,否则编译好的应用程序会崩溃。此外,如果一个系统调用被删除,它所占用的系统调用号也不允许被回收利用。

路径: /usr/include/i386-linux-gnu/asm/unistd. _32.h
在这里插入图片描述

8.4标准I/O库函数

无论是编写系统程序还是应用程序,都离不开I/O这个重要的环节。相对于低级的I/O操作(即系统调用级的I/O),标准I/O库函数处理了很多细节,如缓存分配等。考虑到代码的可移植性,开发人员应该在编写代码时尽可能使用标准库函数。

8.4.1 I/O的管理分类

◆由ANSI标准提供的标准l0库函数几乎被所有的操作系统支持,如winsdows’ 下编写的程几乎不用做任何修改就可以在linux下重新编译运行。如: fopen、fread、 fwrite、fclose。
◆以系统调用的方式给用户提供函数接口(遵循POSIX标准)例如linux操作系统提供的文件I0接口。如: open、 close、 read、 write、 ioctl。
◆系统调用与操作系统直接相关,直接使用系统调用编写的程序的可移植性差。
◆头文件<stdio.h>中声明了标准C的I/O库,标准C的I/O库在所有通用计算机上的C语言实现都是相同的。
◆对于标准I/O操作函数来说,打开或创建一个文件的时 候,会返回一个指向FILE结构体的指针。
◆FILE结构体包含了I/O函数库为管理文件所需要的尽可能多的信息。包括了用于I/O文件的文件描述符、指向流缓存的指针、缓存长度等。
定义路径: /usr/include/libio.h 0别名(typedef): /usr/include/stdio.h
◆头文件<stdio.h> 中声明了标准C的I/O库,标准C的I/O库在所有通用计算机上的C语言实现都是相同的。
◆对于标准I/O操作函数来说,打开或创建一个文件的时候,会返回一个指FILE结构体的指针。
◆FILE结构体包含了I/O函数库为管理文件所需要的尽可能多的信息。包括了用于I/O文件的文件描述符、指向流缓存的指针、缓存长度等。
◆定义路径: /usr/include/libio.h 0别名(typedef): /usr/include/stdio.h

8.4.2打开流

◆头文件: #include <stdio.h>
定义函数: FILE* fopen(const char *pathname, const char *mode);
◆函数说明:
➢pathname: 文件的路径及文件名。
➢mode: 流的打开方式。
◆返回值:
➢成功: 返回指向该流的指针。
➢失败: 则返回NUL,并把错误代码存在errno中。

在这里插入图片描述

8.4.3关闭流

◆头文件: #include <stdio.h>
◆定义函数: int fclose(FILE *stream);
函数说明:
➢fclose用来关闭fopen打开的文件。 此动作会让缓冲区的数据写入文件中,并释放系统所提
供的文件资源。
◆返回值:
➢成功返回0;
➢失败返回EOF,并把错误代码存到errno中。

8.4.5 读、写流

打开了流后,对其进行读写操作的方法:
➢每次一个字符

每次一个字符
➢int getchar(void);
➢int getc(FILE *stream);
➢int fgetc(FILE *stream);
➢int putchar(int c);
➢int putc(int C, FILE *stream);
➢int fputc(int C, FILE *stream);

➢每次一行字符

每次-行字符
char *gets(char *buf);
char *fgets(char *buf, int n, FILE *stream);
◆fgets从stream指定的文件中最多读取n-1个字符放到buf所指向的数组中。读到换行符或
文件结束符后不再向后读,最后一个字符读入后接着写入一个空字符。
◆返回值:
➢成功返回buf
➢失败返回NULL
◆注意:
➢gets()丢掉输入 里的换行符
➢fgets()存储输入中的换行符

➢每次一个数据块

每次- -行字符
int puts(const char *str);
int fputs(const char *str, FILE *stream);
◆fputs函数将字符串写入stream指定的文件中,终止字符串的空字符不写入。
返回值:
➢成功返回非负数
➢失败返回EOF
◆注意:
➢puts()为输出添加换行符
➢fputs()不为输出添加换行符

每次一个数据块

size_ t fread(void *ptr, size t size, size t nobj, FILE *stream);
size
t fwrite(const void *ptr, size. t size, size _t nobj, FILE *stream);
◆size是数据块大小, nobj指要读取或写入的数据块个数,stream指定要操作的数据流。
◆注意:两个函数返回的是实际读或写的数据的个数, 而不是整个数据的字节数。

第九章 进程概述

9.1进程的定义

程序:程序是存放在存储质上的一个可执行文件。
进程:进程是程序的执行实例,包括程序计数器、寄存器和变量的当前值。程序是静态的,进程是动态的:

➢程序是一些指令的有序集合,而进程是程序执行的过程。
➢进程的状态是变化的,其包括进程的创建、调度和消亡。

进程整个生命周期可以简单划分为三种状态:
就绪态:进程已经具备执行的一切条件,正在等待分配CPU的处理时间。
执行态:该进程正在占用CPU运行。
等待态:进程因不具备某些执行条件而暂时无法继续执行的状态。
在这里插入图片描述

9.2 了解进程

每个进程都由一个进程号来标识,其类型为pid_ _t,
进程号的范围: 0~ 32767.
进程号总是唯一的, 但进程号可以重用。当-个进程终止后,其进程号就可以再次使用了。

在linux系统中进程号由0开始。
进程号为0及1的进程由内核创建。
➢进程号为0的进程通常是调度进程,常被称为交换进程(swapper)。
➢进程号为1的进程通常是init进程。除调度进程外, 在linux 下面所有的进程都由进程init进程直接或者间接创建。

进程号(PID):标识进程的一个非负整型数。
父进程号(PPID) :任何进程(除init进程)都是由另一 个进程创建,该进程称为被创建进程的父进程,对应的进程号称为父进程号(PPID)。
进程组号(PGID) :进程组是一个或多个进程的集合。他们之间相互关联,进程组可以接收同一终端的各种信号,关联的进程有一个进程组号(PGID) 。

Linux操作系统提供了三个获得进程号的函数getpid(、 getppid0、 getpgid(。
需要包含头文件:

#include <sys/types.h>
#include <unistd.h>
> pid. _t getpid(void)
➢返回值:本进程号(PID)
> pid_ _t getppid(void)
➢返回值:调用此函数的进程的父进程号(PPID)
pid_ _t getpgid(pid _t pid)
➢参数: 0当前PGID,否则为指定进程的PGID
➢返回值:进程组号(PGID)

在linux环境下,创建进程的主要方法是调用以下函数:

#include <sys/types.h>
#include <unistd.h>
pid. _t fork(void);

fork函数:创建一个新进程

pid_ t fork(void)

功能:
➢fork()函数用于从一个已存在的进程中创建一个新进程,
       新进程称为子进程,原进程称为父进程。

返回值:
➢成功:子进程中返回0,父进程中返回子进程ID。
➢失败:返回-1。

使用fork函数得到的子进程是父进程的一个复制品,它从父进程处继承 了整个进程的地址空间。
地址空间:包括进程上下文、进程堆栈、打开的文件描述符、信号控制设定、 进程优先级、进
程组号等。
子进程所独有的只有它的进程号,计时器等。因此,使用fork函数的代价是很大的。

9.3 一些进程分类

僵尸进程(Zombie Process) :父进程未运行结束,已运行结束的子进程。
孤儿进程(Orphan Process) : 父进程运行结束,但子进程未运行结束的子进程。
守护进程(精灵进程) (Daemon process) :守护进程是个孤儿进程,它提供系统服务,

常常在系统启动时启动,仅在系统关闭时才终止。这种进程脱离终端,在后台运行。

9.4 进程的动作

进程在一定的时间内没有任何动作,称为进程的挂起
#include <unistd.h>
unsigned int sleep(unsigned int sec);
功能: 进程挂起指定的秒数, 直到指定的时间用完或收到信号才解除挂起。
返回值:若进程挂起到sec指定的时间则返回0, 若有信号中断则返回剩余秒数。
注意:进程挂起指定的秒数后程序并不会立即执行,系统只是将此进程切换到就绪态。

父子进程有时需要简单的进程间同步,如父进程等待子进程的结束。
linux下提供了以下两个等待函数wait(、waitpid(。
需要包含头文件:
➢#include <sys/types.h>
➢#include <sys/wait.h>
pid_ t wait(int *status);
功能:
等待子进程改变状态,如果子进程终止了,此函数会回收子进程的资源。
调用wait函数的进程会挂起,直到它的一个子进程退出或收到一个不能被忽视的信号
时才被唤醒。
若调用进程没有子进程或它的子进程已经结束,该函数立即返回。
参数:函数返回时,参数status中包含子进程退出时的状态信息。子进程的退出信息在一 个
int中包含了多个字段,用宏定义可以取出其中的每个字段。
返回值:
➢如果执行成功则返回子进程的进程号。
➢出错返回-1,失败原因存于errno中。

pid_ t waitpid(pid _t pid, int *status, int options);
功能:等待子进程改变状态,如果子进程终止了,此函数会回收子进程的资源。
返回值:
如果执行成功则返回子进程ID。
出错返回-1,失败原因存于errno中。

参数pid的值有以下几种类型:
pid>0:等待进程ID等 于pid的子进程。
pid=0等待同一个进程组中的任何子进程,如果子进程已经加入了别的进程组,waitpid不会等待它。
pid=-1:等待任一子进程, 此时waitpid和wait作用一 样。
pid<-1: 等待指定进程组中的任何子进程,这个进程组的ID等于pid的绝对值。

.status参数中包含子进程退出时的状态信息。

options参数能进一步控制waitpid的操作: 同wait, 阻塞父进程,等待子进程退出。
WNOHANG:没有任何已经结束的子进程, 则立即返回。
WUNTRACED如果子进程已暂停则马上返回,且子进程的结束状态不予以理会。

在linux下可以通过以下方式结束正在运行的进程:
void exit(int value); void_ exit(int value);
exit函数:结束进程执行

#include <unistd.h>
void exit(int value)
参数: status: 返回给父进程的参数(8位有效)

_exit函数: 结束进程执行
#include <unistd.h>
void
exit(int value)
参数: status:返回给父进程的参数(低8位有效)。

exit和_ exit函数的区别:
exit为库函数,而_ _exit为系统调用
在这里插入图片描述
进程在退出时可以用atexit函数注册退出处理函数。
#include < stdlib.h>
int atexit(void (*function)(void);
功能:注册进程正常结束前调用的函数。
参数: function: 进程结束前,调用函数的入口地址。
-个进程中可以多次调用atexit函数注册清理函数,正常结束前调用函数的顺序和注册时的
顺序相反。

第十章 管道、命名管道

10.1 进程间通信概述

进程间通信(IPC:InterProcesses Communication)
◆进程是-个独立的资源分配单元,不同进程(这里所说的进程通常指的是用户进程)之间的资源是独立的,没有关联,不能在一个进程中直接访问另一个进程的资源(例如打开的文件描述符)。
◆进程不是孤立的,不同的进程需要进行信息的交互和状态的传递等,因此需要进程间通信。

10.1.1进程间通信功能

进程间通信功能:
◆数据传输: -个进程需要将它的数据发送给另一个进程。
◆资源共享:多个进程之间共享同样的资源。
◆通知事件:一个进程需要向另一个或一-组进程发送消息,通知它们发生了某种事件。
◆进程控制:有些进程希望完全控制另一个进程的执行(如Debug进程),此时控制进程希望能够拦截另-个进程的所有操作,并能够及时知道它的状态改变。

10.1.2 进程间通信发展

linux进程间通信(IPC)由以下几个部分发展而来
最初的UNIX进程间通信
SYSTEM V进程间通信
POSIX进程间通信(POSIX:Portable Operating System interface可移植操作系统接口)
Socket进程间通信
Linux把优势都继承了下来并形成了自己的IPC

10.1.3 Linux操作系统支持的主要进程间通信的通信机制

在这里插入图片描述

10.2 管道

10.2.1管道(pipe)又称无名管道。

无名管道是一种特殊类型的文件, 在应用层体现为两个打开的文件描述符。
在这里插入图片描述

10.2.2 管道的特点

管道是最古老的UNIX IPC方式,其特点是:
◆半双工,数据在同一时刻只能在一个方向上流动。
◆管道不是普通的文件,不属于某个文件系统,其只存在于内存中。
◆管道没有名字,只能在具有公共祖先的进程之间使用。
◆管道的缓冲区是有限的。管道是一个固定大小的缓 冲区。在Linux中, 该缓冲区的大小为4Kbyte.
◆管道所传送的数据是无格式的,这要求管道的读出方与写入方必须事先定好数据的格式,如多少字节算一个消息等。
◆数据只能从管道的一端写入,从另一端读出。
◆从管道读数据是一次性操作,数据- -旦被读走, 它就从管道中被抛弃,释放空间以便写更多的数据。

10.2.3 管道的操作命令

#include <unistd.h>
int pipe(int filedes[2]);

◆功能: 经由参数filedes返回两个文件描述符
◆参数:
filedes为int型数组的首地址,其存放了管道的文件描述符fd[0]、fd[1]。
filedes[0]为读而打开, filedes[1]为写而打开 管道,filedes[0]的输出是filedes[1]的输入。
◆返回值:
➢成功:返回0
➢失败: 返回-1
在这里插入图片描述

10.2.4 文件描述符概述

◆文件描述符是非负整数,是文件的标识。
◆内核利用文件描述符(file descriptor)来访问文件。
◆利用open打开-个文件时, 内核会返回一个文件描述符。每个进程都有一-张文件描述符
的表,进程刚被创建时,其计录了默认打开的标准输入、标准输出、标准错误输出三个
设备文件的文件描述符0、1、 2。在进程中打开其他文件时, 系统会返回文件描述符表中
最小可用的文件描述符,并将此文件描述符记录在表中。

10.2.5 dup 和dup2

dup和dup2是两个非常有用的系统调用,都是用来复制-个文件的描述符。

int dup(int oldfd);
int dup2(int oldfd, int newfd);

dup和dup2经常用来重定向进程的stdin、stdout和 stderr。

dup函数
#include <unistd.h>
int dup(int oldfd);
功能:复制oldfd文件描述符, 并分配一个新的文件描 述符,新的文件描述符是调用进程文件描述符表中最小可用的文件描述符。
参数: oldfd: 要复制的文件描述符oldfd。
返回值:
➢成功:新文件描述符。
➢失败:返回- 1,错误代码存于errno中。
dup函数
注意:新的文件描述符和oldfd指向的是同一 个文件, 共享oldfd所有的锁定、读写位置和
各项权限或标志,但文件描述符之间并不共享close- on-exec标志。

dup2函数
#include <unistd.h>
int dup2(int oldfd, int newfd)
功能: 复制一份打开的文件描述符oldfd,并分配新的文件描述符newfd, newfd也标识
oldfd所标识的文件。
注: newfd是小于 文件描述符最大允许值的非负整数,如果newfd是一 个已经打开的文件
描述符,则首先关闭该文件,然后再复制。
dup2函数
参数:
➢要复制的文件描述符oldfd
➢分配的新的文件描述符newfd
返回值:
➢成功:返回newfd
➢失败:返回-1,错误代码存于errno中

10.3 命名管道

10.3.1 命名管道的特点

命名管道(FIFO)和管道(pipe)基本相同,但也有一些显著的不同,其特点是:

  1. FIFO在文件系统中作为一个特殊的文件而存在。
  2. 虽然FIFO文件存在于文件系统中,但FIFO中的内容却存放在内存中,在Linux中,该缓冲区的大小为4Kbyte。
  3. FIFO有名字,不同的进程可以通过该命名管道进行通信。
  4. FIFO所传送的数据是无格式的。
  5. 从FIFO读数据是一次性操作,数据-旦被读, 它就从FIFO中被抛弃,释放空间以便写更多的数据。
  6. 当共享FIFO的进程执行完所有的I/O操作以后,FIFO将继续保存在文件系统中以便以后使用。

10.3.2 FIFO文件的创建

#include <sys/types.h>
#include <sys/stat.h>
int mkfifo( const char *pathname, mode_ _t mode);
参数:
➢pathname: FIFO的路径名+文件名。
➢mode: mode_ _t类型的权限描述符。

返回值:
➢成功:返回0
➢失败: 如果文件已经存在,则会出错且返回-1。FIFO文件的读写
◆因为使用pipe的进程通过继承获得了pipe的文件描述符,所以pipe仅需要创建而不需要打开。
◆但是FIFO则需要打开,因为使用它们的进程可以没有任何关系。
◆一般文件的I/O函数都可以作用于FIFO,如open、close、 read、 write等。
当打开FIFO时,非阻塞标志(O_ NONBLOCK)产生下列影响:
不指定0_ NONBLOCK(即不写| O_ NONBLOCK):
➢只读open要阻塞到某个其他进程为写而打开此FIFO。
➢只写open要阻塞到某个其他进程为读而打开此FIFO。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值