共计 2026 个字符,预计需要花费 6 分钟才能阅读完成。
问题:如何加强服务端能力,同时反对多个客户端?
Linux 的设计哲学:所有皆文件
Linux 中的文件是什么?
-
侠义:
- 文件系统中物理意义上的文件(逻辑上关联的数据汇合)
-
狭义:
- 设施,通道,内存,。。。
- Linux 治理的所有对象
了解文件描述符
- 文件描述符是一个非负整数,实质是一个句柄
- 所有对用户(程序员)通明的资源标识都能够看作句柄
- 用户应用文件描述符(句柄)与内核交互
- 内核通过文件描述符操作对应资源的数据结构
所有皆文件的意义
- 对立各种设施的操作形式(open,read,write,close)
-
如:
- IO 设施(命令行,显示器)
- 网络设备(网卡)
- …
编程试验:以文件形式操作命令行
#include <stdio.h>
#include <unistd.h>
int main()
{
int iofd = 0;
char s[] = "D.T.SoftWare\n";
int len = 0;
write(iofd, s, sizeof(s));
len = read(0, s, 5);
s[len] = 0;
printf("%s\n", s);
return 0;
}
输入:
book@100ask:~/Desktop$ ./a.out
D.T.SoftWare
12345
12345
book@100ask:~/Desktop$
...
book@100ask:~/Desktop$ ./a.out
D.T.SoftWare
12345678
12345 // 留神这里为什么只输入了 12345
book@100ask:~/Desktop$ 678 // 留神这里为什么输入 678
678: command not found
答:在 a.out 应用程序中输出了 "12345678", 但应用程序只读取了 5 个字符,即 "12345"。当应用程序完结,a.out 所在终端获得所有权,失去 "678", 并尝试将其当作命令解析
事件相干函数的分类
-
阻塞式函数
- 函数调用后须要期待某个事件产生后才会返回
-
非阻塞式函数
- 函数调用后可能及时返回(仅标记期待的事件)
- 事件产生后以回调形式传递
阻塞 VS 轮询
- 轮询指依序拜访每一个相干设施是否须要服务的形式
- 轮询可用于解决阻塞函数导致程序无奈继续执行的问题
神奇的 select() 函数
- select() 用于 监督指定的文件符 是否产生事件
- 可通过轮询的形式检测指标文件(事件产生则标记发生变化)
- 依据事件类型做出具体解决(如:读数据)
int select(int maxfd, // maxfd = n(最大的文件描述符) + 1,标记监听的描述符范畴 [0 - maxfd-1]
fd_set *readset, // 查看可读性
fd_set *writeset, // 查看可写性
fd_set *exceptset, // 查看异样
const struct timeval *timeout); // 期待 IO 的时长
select() 函数的应用步骤
select() 相干数据类型及操作
fd_set 的每一位标识一个文件描述符,当某一位为 1,则示意监听
* FD_SERO(fd_set *fdset); // 将 fd_set 变量的所有位设置为 0
* FD_SET(int fd, fd_set*fdset); // 在 fd_set 中指定要监听的 fd
* FD_CLR(int fd, fd_set*fdset); // 在 fd_set 中剔除 fd, 不再监听
* FD_ISSET(int fd, fd_set*fdset); // 在 fd_set 产看是否蕴含 fd
编程试验:select() 初体验
#include <sys/select.h>
#include <sys/time.h>
#include <stdio.h>
#include <unistd.h>
int main()
{
int iofd = 0;
char s[] = "D.T.SoftWare";
int len = 0;
fd_set reads = {0};
fd_set temps = {0};
struct timeval timeout = {0};
FD_ZERO(&reads);
FD_SET(iofd, &reads);
while (1) {
int r = -1;
temps = reads; // NOTICE !!!
timeout.tv_sec = 0;
timeout.tv_usec = 50000;
r = select(1, &temps, 0, 0, &timeout);
if (r > 0) {len = read(iofd, s, sizeof(s)-1);
s[len] = 0;
printf("Input: %s\n", s);
}
else if (r == 0) {
static int count = 0;
usleep(10000);
count++;
if (count > 100) {printf("do something slse\n");
count = 0;
}
}
else {break;}
}
return 0;
}
输入:
book@100ask:~/Desktop$ ./a.out
hello word
Input: hello word
do something slse
...
...
思考:应用 select() 函数能够扩大服务端性能吗?如果能够,具体怎么实现?
正文完