没有合适的资源?快使用搜索试试~ 我知道了~
温馨提示
试读
315页
Linux系统编程是指在Linux操作系统上进行程序开发的一种形式。它涵盖了多个方面,包括文件操作、进程管理、内存管理、网络编程等。 Linux系统编程涵盖了众多领域,从基础的文件操作到高级的网络通信和多线程编程,为开发者提供了广泛的功能和灵活性。在这个领域工作的开发者需要深入了解Linux内核和系统底层的工作原理。 Linux 系统编程是指在 Linux 操作系统上进行应用程序和工具开发的一系列活动。这种编程涉及到与 Linux 操作系统核心交互,以实现各种功能,如文件操作、进程管理、网络通信等。Linux 系统编程通常需要直接调用系统调用,使用 C 或 C++ 等低级编程语言进行开发。
资源推荐
资源详情
资源评论
Linux系统编程
By NUISTWF
Linux系统编程
一、IO
1、stdio
1.1 fopen/fclose
1.2 fgetc/fputc/fgets/fputs
1.3 fread/fwrite
1.4 printf/scanf/atoi/sprintf
1.5 fseek/ftell/rewind/fflush
1.6 getline/mygetline
1.7 临时文件tmpfile/strstr
2、sysio
2.1 文件描述符实现原理
2.2 open/close/creat
2.3 read/write/lseek
2.4 IO区别fileno/fdopen
2.5 IO效率和文件共享
2.6 原子操作dup/dup2
2.7 同步sync/fcntl/ioctl
3、advio
3.1 有限状态机编程
3.2 IO多路转接select/poll
3.3 readv/writev
3.4 内存映射mmap
3.5 文件锁
二、文件系统
1、目录和文件
1.1 文件属性stat/空洞文件
1.2 文件类型/umask/chmod/t
1.3 文件系统FAT/UFS
1.4 链接文件和目录操作
1.5 分析目录/读取目录glob/du
2、系统数据文件和信息
2.1 口令文件passwd/getpwuid
2.2 组文件group/getgrgid
2.3 加密文件shadow/crypt
2.4 时间戳函数time
3、进程环境
3.1 进程的终止方式echo
3.2 钩子函数atexit
3.3 命令行参数getopt/strncat
3.4 环境变量environ
3.5 程序空间和手工装载库
3.6 跳转setjmp/资源getrlimit
三、进程基础
1、进程标识符pid
2、父子进程的产生fork
3、释放资源waitpid/交叉分配
4、exec函数族/myshell
NUISTWF
No. 1 / 315
5、用户和组权限/解释器文件
6、system/popen/进程会计和时间
7、守护进程
8、系统日志
四、并发(信号和线程)
1、信号
1.1 信号/signal
1.2 可重入/信号的响应过程
1.3 函数 kill/raise/alarm/pause
1.4 漏桶/令牌桶和令牌桶封装
1.5 多任务计时/setitimer
1.6 信号集/屏蔽字/pending
1.7 sigsuspend/sigaction
1.8 实时信号和信号总结
2、线程
2.1 线程的概念标识与创建
2.2 线程终止和栈清理
2.3 线程的取消与竞争故障
2.4 互斥量/条件变量/信号量
2.5 线程/互斥量/条件变量属性/clone
2.6 线程重入和openmp标准
五、进程间通信
1、管道
2、消息队列
3、信号量数组
4、共享内存
5、网络编程socket
5.1 socket/报式实例
5.2 广播和多播
5.3 TCP/流式实例
六、结尾
一、IO
1、stdio
1.1 fopen/fclose
无内存泄漏,无写越界,不要当自己在写main函数,自己永远在写小模块。
stdio/sysio(标准io和系统io)(man2是系统io,man3是标准io)。
fopen->open (Linux)
fopen->openfile (Windows)
标准io是fopen,相当于各种系统的接口,后面的open和openfile是各个系统的系统IO,也就是文件IO
(sysio)。
FILE *fopen(const char *path, const char *mode);
int fclose(FILE *fp);
NUISTWF
No. 2 / 315
不能更改常量,通过指针更改一个字符不可以;
const限制,
const char *a = "Hello";
char *b = "World";
*a = 'M'; // 错误,尝试修改只读的字符串会导致编译错误
*b = 'W'; // 错误,尝试修改只读的字符串常量会导致编译错误
beginning of the file 代表文件打开第一个有效字节
end of file 代表最后一个有效字节的下一个位置
所有未包含头文件的函数返回均为整型int,此时刚号int和int *类型不匹配报警告:malloc(),若不加头文
件就返回整型如int *p = malloc(sizeof(int)); 会报错,是因为未包含头文件不是直接强转(int *)malloc(),
void *对应任何都是天经地义的。
errno目录:vim /usr/include/asm-generic/errno-base.h
errno是一个C标准库中的全局变量,用于表示在执行系统调用和库函数时发生的错误代码。errno全称
为"error number"(错误编号),其定义在头文件<errno.h>中。
errno的全名是"errno.h",它提供了一组整数常量,每个常量都代表不同类型的错误。当函数调用或系
统调用失败时,它们通常将适当的错误代码设置到errno变量中,以便程序员可以通过查看该变量来确定
错误的性质。可以使用标准库的perror函数将errno的值转换为对应的错误消息。
FILE *返回的指针放在堆上。如果函数有互逆操作,那么函数返回的指针肯定是存放在堆上的。没有互
逆操作,可能在堆也可能在静态区。
定义在堆上的话需要开辟内存空间,那么对应的肯定会释放内存空间,如果这个函数没有对应的关闭函
数(逆函数),那么大概率是不会在堆上的。
是资源就有上限。可以利用fopen来打开文件,但是一个进程中打开的文件数有上限1024个。在不更改
默认环境的情况下,一个进程打开三个流stream(stdin stdout stderr)(标准输入,标准输出和标准错
误)。命令:ulimit -a(-a是指查看所有的):open files (-n) 1024。
0666 & (~umask) (0开头8进制数),若umask=0022,则为000 010 010,取反为111 101 101,跟
0666按位与,则后面俩个第二位为0,第一个为可读,第二个为可写,最后表现出看来就是rw- r-- r--,
则0666变为0644。umask值越大权限就越低,用来降低权限。(掩码)。而chmod设置的是文件权限码。
直接umask可查看umask的值:
fopen.c:
ulimit -a
umask
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
int main()
{
FILE *fp;
fp = fopen("tmp.txt", "r");
NUISTWF
No. 3 / 315
fopen_count.c:
if(fp == NULL) // 返回NULL表示
出错
{
fprintf(stderr, "fopen() failed! errno = %d\n", errno);
perror("fopen() failed"); // 直接打印出错
信息
fprintf(stderr, "fopen() failed: %s\n", strerror(errno)); // 通过函数
strerror中的errno来对应出错信息
exit(1);
}
puts("fopen() success!");
int p = fclose(fp);
if(p == EOF) // 返回EOF表示
出错
{ // 正常情况下都
不用判断,关闭都会成功
fprintf(stderr, "fclose() failed: %s\n", strerror(errno));
exit(2);
}
if(p == 0) // 返回0表示成功
{
fprintf(stdout, "fclose() success!\n");
}
exit(0);
}
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
//测试该进程能一次性打开多少次文件
int main()
{
FILE *fp = NULL;
int count = 0;
while(1)
{
fp = fopen("test.txt", "r");
if(fp == NULL)
{
fprintf(stderr, "fopen() failed! errno: %d and message: %s\n",
errno, strerror(errno));
break;
}
count++;
}
printf("open file counts = %d\n", count);
exit(0);
NUISTWF
No. 4 / 315
1.2 fgetc/fputc/fgets/fputs
宏和函数在某些方面存在关联,但它们也有明显的区别。
1. 相似之处:
宏和函数都可以用来封装一段代码,提供代码重用和模块化。
宏和函数都可以接受参数,根据参数执行相应的操作。
2. 不同之处:
宏是在预处理阶段展开的,而函数是在运行时调用的。宏会在代码编译之前被替换为相应的代
码片段,而函数是在程序运行时根据调用情况执行相应的代码。
宏展开是直接替换文本,没有函数调用的开销,但也可能导致代码膨胀和可读性差。函数调用
则需要在堆栈上分配内存,并跳转到函数代码的入口点执行。
宏可以进行条件编译和编译器相关的操作,而函数不能。例如,可以使用宏定义来针对不同的
平台或编译器定义不同的代码实现。
宏支持代码的嵌套展开,而函数只能通过递归来实现嵌套调用。
总体来说,宏和函数在代码封装和参数传递方面有些相似,但在编译时展开和运行时调用、代码膨胀和
堆栈开销等方面有明显的区别。选择使用宏还是函数取决于具体场景和需求。
当使用宏和函数来封装一段代码时,可以通过以下示例来说明它们的使用:
1. 使用宏封装代码:
在上述示例中,我们使用宏定义了一个名为ADD的宏,它接受两个参数并返回这两个参数的和。在main
函数中,我们使用ADD宏来计算变量x和y的和,并将结果打印输出。
}
int fgetc(FILE *stream);
int getc(FILE *stream);
char *fgets(char *s, int size, FILE *stream);
char *gets(char *s);
int fputc(int c, FILE *stream);
int fputs(const char *s, FILE *stream);
int putc(int c, FILE *stream);
int puts(const char *s);
#include <stdio.h>
// 定义宏,用于计算两个数的和
#define ADD(a, b) ((a) + (b))
int main()
{
int x = 10, y = 20;
int sum = ADD(x, y); // 调用宏进行计算:ADD(x, y)在编译的时候替换成((x) + (y))
printf("Sum: %d\n", sum);
return 0;
}
NUISTWF
No. 5 / 315
剩余314页未读,继续阅读
资源评论
Linux再对我好一点
- 粉丝: 15
- 资源: 2
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- yolo目标检测项目实验
- downloadFile-1.hc
- Centos7.9环境下离线安装开源版Nginx(亲测版)
- C++课程设计:基于Qt的航班信息管理系统
- ADS7822UVerilog驱动,前面传的有点问题
- 基于python的高性能爬虫程序,使用了多线程+缓存+xpath实现的,这里以彼-岸图库为例,实现,仅用于学习交流
- 中分辨率成像光谱仪(MODIS)烧毁面积产品信息MODIS-C6-BA-User-Guide-1.2.pdf
- Screenshot_20240427_172613_com.huawei.browser.jpg
- 关于学习Python的相关资源网站链接及相关介绍.docx
- (HAL库)基于STM32F103C8T6的温控PID系统[Dht11、ESP8266、无线透传、L298N……]
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功