Linux文件I0编程

Linux文件I0编程

Linux文件I0概述

POSIX 规范

POSIX(Portable Operating System Interface)表示可移植操作系 统 接 口 规 范 。 该 标 准 最 初 由 IEEE 制 定 , 目 的 是为了提高UNIX 环 境 下 应 用 程

序 的 可 移 植 性 。 POSIX 已 发 展 成 一 个 庞 大 的 标 准 族 , 其 中 的 POSIX.1 提 供 了

源 代 码 级 别 的C语言应 用 程 序 编 程 接 。 通 俗 地 讲 , 为 一 个 POSIX 兼 容 的 ,操 作 系 统 编 写 的 程 序 , 可 以 在 其 他 任 何 POSIX 操 作 系 统 上 编 译 执 行 。 不 仅 仅是 UNIX, 很 多 操 作 系 统 如 Linux 也 支 持 POSIX 标 准 。

虚拟文件系统

Linux 系 统 成 功 的 关 键 因 素 之 一 就 是 具 有 与 其 他 操 作 系 统 和 谐 共 存的.Linux 的 文 件 系 统 由 两 层 结 构 构 建 ; 第 一 层 是 虚 拟 文 件 系 统(VFS), 第二 层 是 各 种 不 同 的 具 体 的 文 件 系 统 。

VFS 就 是 把 各 种 具 体 的 文 件 系 统 的 公 共 部 分 抽 取 出 来 , 形 成 一 个 抽 象 层 , 是 系 统 内 核 的 一 部 分 。 它 位 于 用 户 程 序 和 具 体 的 文 件 系 统 之 间 。 它 对 用 户 程 序 提 供 了 标 准 的 文 件 系 统 调 用 接 口 , 对 具 体 的 文 件 系 统 ( 比 如 : Ext2、| FATS2 等), 它 通 过 一 系 列 的 对 不 同 文 件 系 统 通 用 的 函 数 指 针 来 调 用 对 应 的 ˇ文 件 系 统 函 数 , 完 成 相 应 的 操 作 。 任 何 使 用 文 件 系 统 的 程 序 必 须 通 过 这 层 接 口 来 访 问 。 通 过 这 样 的 方 式 ,VFS 就 对 用 户 屏 敲 了 底 层 文 件 系 统 的 实 现 细节和差异

VFS 不 仅 可 以 对 具 体 文 件 系 统 的 数 据 结 构 进 行 抽 象 , 以 一 种 统 一 的 数 据接 口 进 行 管 理 , 还 可 以 接 受 用 户 层 的 系 统 调 用 , 如 open()、read() 、write()、 stat(),link() 等 。 此 外 , 它 还 支 持 多 种 具 体 文 件 系 统 之 间 的 相 互 访 问 , 接 受内 核 其 他 子 系 统 的 操 作 请 求 , 例 如 , 内 存 管 理 和 进 程 调 度 。VFS 在 Linux 系统 中 的 位 置 如

查看支持文件系统cat /proc/filesystems

文件和文件描述符

Linux 操 作 系 统 是 基 于 文 件 概 念 的 。 文 件 是 以 字 符 序 列 构 成 的 信 息 载 体 。根 据 这 一 点 , 可 以 把 I/0 设 备 当 作 文 件 来 处 理 。 因 此 , 与 磁 盘 上 的 普 通 文 件进 行 交 互 所 用 的 同 一 系 统 调 用 可 以 直 接 用 于 I[/0 设 备 。 这 样 大 大 简 化 了 系 统对 不 同 设 备 的 处 理 , 提 高 了 效 率 。Linux 中 的 文 件 主 要 分 为 6 种 : 兼 通 文 的,目录 文 件 、 符 号 链 接 文 件 、 管 道 文 件 、 套 接 字 文 件 和 设 备 文 件 ,.

那 么 , 内 核 如 何 区 分 和 引 用 特 定 的 文 件 呢 ? 这 里 用 到 了 一 个 重 要 的 概 念文 件 描 述 符 。 对 于 Linux 而 言 , 所 有 对 设 备 和 文 件 的 操 作 都 是 通 过 文 件 描述 符 来 进 行 的 。 文 件 描 述 符 是 一 个 非 负 的 整 数 , 它 是 一 个 索 引 值 , 并 指 向 在 内核 中 每 个 进 程 打 开 文 件 的 记 录 表 。 当 打 开 一 个 现 存 文 件 或 创 建 一 个 新 文 件 时 ,内 核 就 向 进 程 返 回 一 个 文 件 描 述 符 ; 读 写 文 件 时 , 需 要 把 文 件 描 述 符 作 为 参 数 传 递 给 相 应 的 函 数 。

通 常 , 一 个 进 程 启 动 时 , 都 会 打 开 3 个 流 ; 标 准 输 人 、 标 准 输 出 和 标 准错误,这个3个流分别对应文件描述符0,1和2(对应宏STDIN_FILENO,STDOUT_FILENO 和 STDERR _ FILENO)。

基于 文件描述符的 I/O 操作虽然不能直接移植到类 Linux 以 外的系统上去 (如 Windo ws ), 但它往往是实现某些 I/O 操作的唯一途径,如 Linu x 中低层文件操作函数、多路 1/ O 、 TCP/IP 套接字编程接口等。同时,它们也很好地兼容了 POSIX 标准 ,因此, 可以很方便地移植到任何 POSIX 平台上。基于文件描述符的 I/O 操作是 Linux 中最常用的操作之一

文件 I/O 和标准 I/O 的区别

标准 I/O 和文件 1/O 都可以用来访问文件,它们之间有什么区别呢?

文件 I/O 又称为低级磁盘 I/O, 遵循 POSIX 相关标准。 任何兼容 POSIX 标准的操作系统上都支持文件 I/O。标准 I/O 被称为高级磁盘 I/O,遵循 ANSI C 相关标准。 只要开发环境中有标准 C 库,标准 I/O 就可以使用。 ( Linu x 中使用的是 glibc, 它是标准 C 库的超集。 不仅包含 ANSI C 中定义的函数,还包括 POSIX 标准中定义的函数。因此, Linux 下既可 以使用标准 I/O,也可以使用文件 I/O。)

通过文件 I/O 读写文件时,每次操作都会执行相关系统调用。这样处理的好处是直接读写实际文件,坏处是频繁的系统调用会增加系统开销。标准I/O 可以看作在文件 1/O 的基础上封装了缓冲机制。先读写缓冲区,必要时再访问实际文件,从而减少了系统调用的次数。

文件 I/O 中用文件描述符表示一个打开的文件, 可以访问不同类型的文件如普通文件、设备文件和管道文件等。 而标准 I/O 中用 FILE ( 流)表示一个打开的文件,通常只用来访问普通文件。

文件 I/O 操作

本节主要介绍文件 I/ O 相关函数: open ()、 close()、 read()、 w rite() 、 lseek()和 fcntl()。 这些函数的特点是不带缓冲 , 直接对文件 ( 包括设备 )进行读写操作。 这些函数不是 ANSI C 的组成部分, 而是由 POSIX 相关标准来定义。

2.2.1 文件打开和关闭

1 . 函数说明

open()函数用于创建或打开文件 ,在打开或创建文件时可 以指定文件打开方式及文件的访问权限。

close()函数用于关闭一个被打开的文件。当一个进程终止时,所有打开的文件都由内核自动关闭。 很多程序都利用这 一特性而不显式地关闭一个文件。

2 . 函数格式

open(函数的语法要点如表 2. 1 所示 。

表 2 . 1 open () 函 数 语 法 要 点

在 open (函 数中, f la g s 参数可通过 " | " 组合构成, 但前 3 个标志常量 ( O _ RDONLY 、O _ W RONL Y 以及 O _ RD W R )不能相互组合。 per m s 是文件的存取权限 , 既可以用宏定义表示法,也可以用八进制表示法。

close()函数的语法要点如表 2.2 所示。

  1. 示例代码
c 复制代码
/ * samplel. c * /
#include<stdio.h>
#include<unistd.h>
#include<sys/stat.h>
#include<fcntl.h>
int main ()
	int fd ;
	if ((fd = open(" test.txt " , O_RDWR|O_CREAT|O_T_RUNC,0666))<0){
		perror("fail to open");
		return -l;
	}
	close(fd);
	return O;
}

文件读写

  1. 函数说明
    read()函数从文件中读取数据存放到缓存区中,并返回实际读取的字节数。若返回 0,则表示没有数据可读,即已达到文件尾。 读操作从文件的当前读写位置开始读取内容,当前读写位置自动往后移动。
    write()函数将数据写入文件中 ,并返回实际写入的字节数。写操作从文件的当前读写位置开始写入。对磁盘文件进行写操作时,若磁盘已满, write () 函数返回失败。
  2. 函数格式
    read0函数的语法要点如表 2.3 所示 。

在读普通文件时, 若读到要求的字节数之前已到达文件的尾部,则返回的字节数会小于指定读出的字节数。

write()函数的语法要点如表 2.4 所示 。

  1. 示例代码
c 复制代码
 / * sample2.c */
#include<stdio.h>
#include<unistd.h>
#include <sys/stat.h>
#include < fcntl.h >
#define N 64
int main (
	int fd, nbyte,sum = O;
	char buf[N] ;
	if ((fd = open("test.txt", O_RDONLY)) < 0 ){
		perror("fail to open")
		return -l;
	}
	
	while ((nbyte = read(fd,buf,N))>0)  // 循环从文件中读取数据,直到文件末尾
	{
		sum + = nbyte;//累加每次读取的字节数
	}
	printf("the length of test.txt is %d\n",sum);
	close(fd);
	return 0;
}

文件定位

  1. 函数说明

    lseek()函数对文件当前读写位置进行定位。 它只能对可定位 ( 可随机访问)文件操作。 管道、套接字和大部分字符设备文件不支持此类操作。

  2. 函数格式

    lseek()函数的语法要点如表 2.5 所示。

  3. 示例代码

    下面示例中的 open () 函数带有 3 个 flags 参数: O _C REAT、 O TRUNC 和 O WRONLY,这样就可以对不同的情况指定相应的处理方法。

    实现的功能是从一个文件(源文件)中读取最后 10KB 数据并复制到另一个文件(目标文件)。源文件以只读方式打开,目标文件以只写方式打开,若目标文件不存在,可以创建并设置权限的初始值为 644,即文件所有者可读可写,文件所属组和其他用户只能读。

c 复制代码
/*sample3.c*/
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#inlucde <stdio.h>

#define BUFFER_SIZE 1024
#define SRC_FILE_NAME "src_file"
#define DEST_FILE_NAME "dest_file"
#define OFFSET 10240

int main(){
	int fds,fdd;
	unsigned char buf(BUFFER_SIZE);
	int read len ;
	/*以只读方式打开源文件 *
	if ((fds = open(SRC_FILE_NAME, O_RDONLY))<0){
		perror("fail to open src _file");
		return -1;
	}

	/*以只写方式打开目标文件:若此文件不存在则创建该文件,访问权限值为644*/
 	if ((fdd = open ( DEST _ FILE _ NAME, O _ W RONLYIO _ CREATIO_ TRUNC. 0644)) < 0 ){
 		perror("fail to open dest _ file");
		return -1 :
 	}
	/*将源文件的读写指针移到最后10KB的起始位置* /
	lseek ( fds , -OFFSET, SEEK _ END );
	/* 读取源文件的最后10KB数据井写到目标文件中, 每次读写1KB */
	while ((read _ len = read ( fds , buff , sizeof(buff))) > 0 ){
		write(fdd , buff , read_len);
	}
	close ( fds ) :
	close ( fdd ) :
	return 0;
}

文件锁

  1. fcntl()函 数说明
    前面介绍的 5个基本函数实现了文件的打开、读写等基本操作。这一节将讨论的是在文件已经共享的情况下如何操作,也就是多个程序共同操作一个文件的情况。 Linu x 中通常采用的方法是给文件上锁,来解决对共享的资源的竞争。
    文件锁包括建议性锁和强制性锁。 建议性锁要求每个相关程序在访问文件之前检查是否有锁存在,并且尊重已有的锁。 一般情况下,不建议使用建议性锁, 因为无法保证每个程序都自动检查是否有锁。 而强制性锁是由内核执行的锁, 当一个文件被上锁,进行写入操作的时候, 内核将阻止其他任何程序对该文件进行读写操作。采用强制性锁对性能的影响较大,每次读写操作内核都检查是否有锁存在。
    在 Linux 中,实现文件上锁的函数有 lockf()和 fcntl(), 其中 lockf()用于对文件施加建议性锁,而 fcntl()不仅可以施加建议性锁,还可以施加强制性锁。同时, fcntl o还能对文件的某一记录上锁,也就是记录锁。
    记录锁又可分为读取锁和写入锁,其中读取锁又称为共享锁,多个同时执行的程序允许在文件的同一部分建立读取锁。而写入锁又称为排斥锁,在任何时刻只能有一个程序在文件的某个部分上建立写入锁。 显然,在文件的同一部分不能同时建立读取锁和写人锁。
    fcntl()函数具有丰富的功能 , 它可以对已打开的文件进行各种操作。不仅能够管理文件锁, 还可以获取和设置文件相关标志位以及复制文件描述符等。在本节中,主要介绍利用它建立记录锁的方法。有兴趣的读者可以查看 f cntl 手册了解其他用法。
  2. 函数格式
    用于建立记录锁的 fcntl0函数的语法要点如表 2.6 所示。

若要加 锁整个文件, 可 以将 1_start 设置为 O , I_ whence 设置为 SEEK _ SET , 1_len 设置为 0。

  1. fcnt()使用实例

下面给出了使用 fcntl()函数对文件加记录锁的代码。 首先给 flock 结构体赋予相应的值, 接着调用两次fcntl()函数。 第一次用 F_GETLK 命令判断是否可以执行 flock 结构所描述的锁操作:若成员 1_ty pe 的值为 F_UNLCK ,表示文件当前可以执行相应锁操作;否则成员 1_type 的值表示当前已有的锁类型,并且成员 1_pid 被设置为拥有当前文件锁的进程号。

第二次用 F_SETLK 或 F_SETLKW 命令设置 flock 结构所描述的锁操作,后者是前者的阻塞版本。使用后者时,当不能执行相应上锁/解锁操作时,程序会被阻塞,直到能够操作为止。

文件记录锁的代码具体如下。

c 复制代码
/ * lock _set.c */
int lock_set( int fd, int type ){
	struct flock old _lock , lock ; 
	lock.l_whence = SEEK _SET ;
	lock.l_start = 0;
	lock.1_len = 0 ; 
	lock.l_type = type ;
	lock.l_pid = -1 ;
	/* 判断文件是否可以上锁 */
	fcntl(fd,F_GETLK, &lock);
	if(lock.1_type != F_UNLCK ){
		/*判断文件不能上锁的原因 */
		if(lock.l_type == F_RDLCK){	/*该文件 已有读取锁*/
			printf ("Read lock already set by %d \n",lock.l_pid);
		}
		else if ( lock.l_ t y pe = = F _ WRLCK { /* 该文件已有写 入锁 */
			printf ("Write lock already set by %d\n", lock.l_pid ) :  
		}
	}
	/* 1_ ty pe 可 能 已 被F _ GE T L K修改过 */
	lock.l_type = type;
	/*根据不同的 ty pe值进行阻塞式上锁或解锁*/
	if ((fcntl(fd , F_SETLKW,&lock )) < 0 ){
		printf ( " Lock failed : type = &d \n ". lock.l_ty pe ) ;
		return -l ;
	}

	switch ( lock.l_type ){
		case F_RDLCK :
		{
			printf("Read lock set by %d\n",getpid());
			break :
		}
		case F_WRLCK :
		{
			printf ("write lock set by %d\n ",getpid());
			break;
		}
		case F_UNLCK :
		{
			printf ("Release lock by %d\n",getpid()); 
			return l ;
		}
		
		break ;
	}/* end of switch中 return 0*/;
}

下面的示例是文件写 入锁的测试用例 , 这里首先创建了 一个 hello 文件之后对其上写人锁, 最后释放写入锁。 代码如下。

C 复制代码
/*write lock.c*/
#include <unistd.h>
#include <sy s/file.h>
#include <sys/stat.h>
#include <st dio.h>
#include <stdlib.hs
int lock_set(int fd , int type);\

int main(void){
	int fd :
	/*首先打开文件*/
	if((fd = open ( "hello" , O _ RD WR)) < 0){
		perror("fail to open");
		return -1;
	}

	/*给文件上写入锁*/
	lock _set ( fd , F_WRLCK ) ;
	getchar(); // 等待用户键盘输人
	/*给文件解锁 */
	lock _set(fd , F_ UNLCK);
	getchar0;
	close(fd);
	return O :
}

运行如下命令编译程序。

gcc -o write _ lock write _ lock.c lock _ set.c

建议读者开启两个终端,并且在两个终端上同时运行该程序,以达到多个程操作一个文件的目的。

终端一如下。

由此可见,写入锁为互斥锁,同一时刻只能有一个写人锁存在。

接下来的程序是文件读取锁的测试用例,原理和上面的程序一样。

C 复制代码
 /*fcntl_read.c*/
#include <unistd.h>
#include <sys/file.h> #include <sys/types.h> #include <sys/stat.h> #include <st dio. h >
#include <stdlib.h >
#include "lock _ set.c"
int main (void){
	int fd;
	fd = open("hello", O _ RDwR | O _ CREAT, 0644 ) ; 
	if ( fd < 0)
	{
		printf("Open file error \n"); 
		exit (1);
	}
	/*给文件上读取锁 */
	lock _set(fd.F_RDLCK);
	getchar();
	/*给文件解锁 */
	lock _ set(fd,F_UNLCK);
	getchar();
	close(fd);
	exit(0);
}

读者可以将此结果与写人锁的运行结果相比较, 可以看出 , 读取锁为共享锁, 当进程 5009 已设置读取锁后 , 进程 5010 仍然可以设置读取锁。

实验内容一一生产者和消费者

  1. 实验目的
    通过编写文件读写及上锁的程序,进一步熟悉 Linux 中文件 I/O 相关的应用开发,并且熟练掌握 open()、 read()、 write (、 fcntl(等函数的使用方法。
  2. 实验内容
    使用文件来模拟 FIFO (先进先出 )结构以及生产者一消费者运行模型。
    实验中需要打开两个虚拟终端, 分别运行生产者程序 ( producer )和消费者程序 ( customer )。 两个程序同时对同 一个文件进行读写操作。 因为这个文件是共享资源,所以使用文件锁机制来保证两个程序对文件的访问都是原子操作。
    先启动生产者进程, 它负责创建模拟 FIFO 结构的文件 ( 其实是一个普通文件)并投入生产,即按照给定的时间间隔,向文件写入自动生成的字符(在程序中用宏定义选择使用数字还是使用英文字符)。生产周期以及要生产的资源数通过参数传递给程序。(默认生产周期为 1s,要生产的资源总数为 10个字符,默认生产总时间为 10s。)
    后启动的消费者进程按照给定的数目进行消费。首先从文件中读取相应数目的字符并在屏幕上显示,然后从文件中删除刚才消费过的数据。为了模拟 FIFO 结构,此时需要使用两次复制来实现文件内容的前移。 每次消费的资源数通过参数传递给程序,默认值为 10个字符。

(2) 编写代码 。

本实验中的生产者程序的源代码如下, 其中用到的 lock_set()函数可参照第 2.2.4 节。

c 复制代码
/* producer.c */
2
#include <stdio.h>
#include <unistd .h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include "mylock.h"
/*级冲 区大小最大镇*/
#define MAXLEN	10
#define ALPHABET	1 /*表示使用英文字符 */
#define ALPHABET_START 'a' /*头一个字符, 可以用 A */
#define COUNT_OF_ALPHABET 26 /*字母字符的个数 */ 
#define DIGIT	2 /*表示使用数字字符*/
#define DIGiT_START '0' /*头一个字符*/
#define COUNT _ OF _ DIGIT 10 /*数字字符的个数*/
#define SIGN_TYPE ALPHABET /*本实例选用英文字符*/
const char * fifo_file = "./ my fifo"; /*仿真 FIFO文件名*/
char buff [MAXLEN]; /*缓冲区*/


/* 功能: 生产一个字符并写入仿真FIFO文件中 
int product(void){
	int fd;
	unsigned int sign_type,sign_start,sign_count,size;
	static unsigned int counter = 0;
	
	/*打开仿真FIFO文件*/
	if ((fd = open(fifo_file,O_CREATIO_RDWR|O_APPEND, 0644)) < 0 ){
		printf("Open fifo file error\n ");
		exit(1);
	}
	sign_type = SIGN _TYPE;
	switch(sign_type)
	{
		case ALPHABET:/*英文字符*/
		{
			sign_start = ALPHABET_START;
			sign_count = COUNT_OF_ALPHABET;
		}
		break;
		case DIGIT :/*数字字符*/
		{
			sign_start = DIGIT_START;
			sign_count = COUNT_OF_DIGIT;
		}
		break;
		default:
		{
		return -1;
		}
	}/*end of switch*/
	sprintf(buff, "%c",(sign_start + counter))
	counter = (counter + 1)%sign_count;

	lock_set(fd,F_WRLCK); /*上写人锁*/
	if((size = write(fd , buff,strlen(buff))) < 0 )
	{
		printf("Producer:write error \n ");
		return - 1;
	}
	lock_set(fd.F_UNLCK); /*解锁*/
	close(fd);
	return 0;
}
int main ( int argc,char *argv [] ){
	int time_step = 1 ;   	/*生产周期*/ 
	int time_life = 10;		/*需要生产的资源总数*/
	
	if(argc > 1)
	{ 
		/*第一个参数表示生产周期 */
		sscanf ( argv[1],"%d",&time.step);
	}
	if(argc>2)
	{
		/*第二个参数表示需要生产的资源数*/
		sscanf(argv[2],"%d",&time_life);
	}
	while(time_life--)
	{
		if(product() < 0)
		{
			break;
		}
		sleep(time_step);
	}
	exit(EXIT_SUCCESS);
}

本实验中的消费者程序的源代码如下。

c 复制代码
/ * customer.c * /
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <f cntl.h>
#define MA X _ FILE _ SIZE 100 * 1024 * 1024  /*100MB*/
const char *fifo_file = "./ myfifo"; /* 仿真 FIFO文件名 */
const char *tmp_file = "./tmp"; /*临时文件名 /

/*资源消费函数*/
int customing ( const char * my fifo, int need ){
	int fd ;
	char buff;
	int counter = 0 ;
	if ( ( fd = open ( myfifo, O_RDONLY)) < 0 )
	5
	printf ( "Function customing error\n ") ;
	return -1;
	printf ( "Enjoy;");
	Iseek ( fd,SEEK_SET,0); 
	while ( counter < need ){
		while (( read ( fd , &buff . 1 ) = = 1) && ( counter < need)){
			fputc (buff,stdout) : /*消费就是在屏幕上简单地显示 * /
			counter++;
		}
	}
	fputs( "\n",stdout);
	close(fd) ;
	return 0;
}

/* 功能 :从 sour_file 文件的offset偏移处开始将 count字节数据复制到 dest_file文件 */
int my filecopy(const char * sour_file,
const char * dest_file, int offset,int count, int copy _mode){
	int in_file, out_file; 
	int counter = 0;
	char buff _ unit ;
	if ((in_file = open (sour _ file, O_ RDONLY IO _ NONBLOCK) ) < O){
			printf(" F unction my filecopy error in source file\n ") ;
		return -l ;
	}
	if ((out _ file = open (dest_ file,
	O_CREATIO _ RDWRIO _ TRUNCI0 _ NONBL0CK. 0644)) < 0)
	{
		printf("Function myfilecopy error in destination file :") ;
	return -1 ;
	}
	
	Iseek(in_file. off set , SEEK_SET);
	while ((read (in_file. &buff_unit . 1) = = 1 ) && (counter < count) )
	{
		write (out_file . &buff_unir . 1);
		counter++:
	}
	close(in_file);
	close(out_file);
	return 0:
}



/*功能: 实现FIFO消费者*/
int custom (int need)
{
	int fd;
	/*对资源进行消费: need 表示该消费的资源数目*/
	customing (fifo_file.need);
	if(( fd = open( fifo _ file, O _ RD W R)) < 0){
		printf( " Function my filecopy error in source_file: ") ;
		return -l:
	}
	/*为了 模拟 FIF O结构, 对整个文件内容进行平行移动 */
	lock_set(fd,F_WRLCK);
	myfilecopy(fifo_file, tmp_file, need , MAX_FILE_SIZE , 0); 
	my filecopy( tmp_ file, fifo _file, 0, MAX _ FILE _ SIZE , 0);
	lock _set( fd , F_UNLCK);
	unlink(tmp_file):
	close(fd);
	return 0;
}


int main(int argc,char * arg v [])
{
	int customer_capacity = 10;
	if (argc > 1) /*第一 个参数指定需要消费的资源数目, 默认值为10*/
	{
		sscanf (argv[1]."%d", &customer_capacity);.
	}
	
	if(customer _capacity > 0)
	{
		custom(customer_capacity);
	}
	exit(EXIT_SUCCESS);
}
相关推荐
skywalk81635 小时前
在FreeBSD的Uubntu兼容环境下安装Reasonix
linux·运维·freebsd
^yi6 小时前
【Linux系统编程】对操作系统的理解
linux·运维·服务器·操作系统·系统调用·os
Kina_C6 小时前
LVS-NAT 负载均衡实验从环境搭建到规则持久化
linux·运维·服务器·负载均衡·lvs
小肝一下6 小时前
7. 库制作与原理
linux·c语言·操作系统·bash·shell·动静态库
hkj88087 小时前
Ubuntu 20.04 安装 OpenJDK 17
linux·运维·ubuntu
huainingning7 小时前
防火墙重启后ssl登录提示证书过期临时解决方法
linux·服务器·ssl
Fu_Lin_7 小时前
Qt嵌入式从零基础到精通(01):Qt嵌入式开发全景图:从桌面Qt到ARM Linux
linux·arm开发·qt·qt5·嵌入式linux
lczllx7 小时前
从 TCP 90μs 到 SHM 28μs:我的 RPC 框架零拷贝优化历程
linux·后端
Kina_C8 小时前
LVS-DR 模式负载均衡实战从原理到部署与验证
linux·运维·服务器·负载均衡·lvs
盐焗鹌鹑蛋8 小时前
【Linux】权限
linux