#include <myheader.h>
//select函数超时现象
int main(int argc, const char *argv[])
{
//定义检测容器
fd_set readfds;
//2 清空容器
FD_ZERO(&readfds);
//3 将文件描述符放入集合当中
FD_SET(0,&readfds);
//定义超时时间变量
struct timeval tv ={5,0}; //1秒=1000毫秒 1毫秒=1000微妙
while(1)
{
tv.tv_sec=5;
tv.tv_usec=0;
int res=select(1,&readfds,NULL,NULL,&tv);
if(res==-1)
{
perror("select error");
return -1;
}else if(res==0)
{
printf("time out\n");
return -1;
}
//判断
if(FD_ISSET(0,&readfds))
{
int num=0;
scanf("%d",&num);
printf("键盘触发输入操作输入:%d\n",num);
}
}
return 0;
}
select的超时检测
#include <myheader.h>
// poll超时现象
int main(int argc, const char *argv[])
{
//定义文件描述符集合
struct pollfd pfd;
pfd.fd=0; //表示检测的是0号文件描述符
pfd.events=POLLIN; // 表示检测事件
//调用函数
while(1)
{
int res =poll(&pfd,1,5000);
if(res ==-1)
{
perror("poll error");
return -1;
}
else if(res ==0)
{
printf("time out\n");
return -1;
}
//判断
if(pfd.revents ==POLLIN)
{
int num=0;
scanf("%d",&num);
printf("触发键盘输入:%d\n",num);
}
}
return 0;
}
① IO多路复用的原理
多路复用:多路复用是指通过一个线程同时监听多个IO事件的就绪状态。在传统的阻塞IO模型中,
每个IO操作都需要一个独立的线程来处理,当有大量的IO操作时,会导致线程数量的增加,
从而带来线程切换和上下文切换的开销。而多路复用通过使用一个线程来监听多个IO事件,
避免了线程数量的增加,减少了线程切换和上下文切换的开销。
IO事件就绪通知:多路复用机制通过操作系统提供的系统调用(如select、poll、epoll等)
来监听多个IO事件的就绪状态。当有任何一个IO事件就绪时,操作系统会通知应用程序,
告知哪些IO事件已经准备好可以进行读取或写入操作。
非阻塞IO:多路复用机制通常与非阻塞IO配合使用。在非阻塞IO模型中,
当一个IO操作无法立即完成时,不会阻塞线程,而是立即返回一个错误码或特定的状态,
应用程序可以继续处理其他IO操作或其他任务,
提高了系统的并发性能。
事件循环:多路复用机制通过事件循环来处理就绪的IO事件。事件循环会不断地监听IO事件的就绪状态,
当有IO事件就绪时,会调用相应的回调函数来处理该事件。通过事件循环的方式,可以高效地处理多个IO操作。
② 实现IO多路复用可以使用哪些函数完成
select poll epoll 函数
③ select 和poll的区别
select、poll、epoll 区别总结:
1、支持一个进程所能打开的最大连接数
select:单个进程所能打开的最大连接数有FD_SETSIZE宏定义,其大小是32个整数的大小
(在32位的机器上,大小就是3232,同理64位机器上FD_SETSIZE为3264),当然我们可以对进行修改,
然后重新编译内核,但是性能可能会受到影响,这需要进一步的测试。
poll:poll本质上和select没有区别,但是它没有最大连接数的限制,原因是它是基于链表来存储的。
epoll:虽然连接数有上限,但是很大,1G内存的机器上可以打开10万左右的连接,
2G内存的机器可以打开20万左右的连接。
2、fd剧增后带来的IO效率问题
select:因为每次调用时都会对连接进行线性遍历,所以随着FD的增加会造成遍历速度慢的
“线性下降性能问题”。
poll:同上
epoll:因为epoll内核中实现是根据每个fd上的callback函数来实现的,
只有活跃的socket才会主动调用callback,所以在活跃socket较少的情况下,
使用epoll没有前面两者的线性下降的性能问题,但是所有socket都很活跃的情况下,可能会有性能问题。
3、 消息传递方式
select:内核需要将消息传递到用户空间,都需要内核拷贝动作
poll:同上
epoll:epoll通过内核和用户空间共享一块内存来实现的。
④ 在UDP通信过程中,能否使用connect函数?为什么?有什么好处?
1>UDP虽然是面向无连接的通信方式,但是也可以使用connect函数
2>UDP使用connect 函数,是跟指定的某个端点建立唯一通信,在没有断开之前
其余的端点不接受通信。
3>如何断开:只需要将连接函数中,对端地址信息结构体中的sin_family成员属性设置为
AF_UNSPEC进行连接即可
4>连接的好处:能够实现数据的稳定连接,不至于再跟某个端点进行通信时,被其余
端点打断
5>能够提高传输效率
⑤ OSI 7层网络体系结构有哪些
应用层 表示层 会话层 运输层 网络层 数据链路层 物理层
⑥ 4层网络体系结构有哪些
应用层 传输层 网际层 网络接口层
⑦ ARP HTTP TFTP IP TCP 说出全称和所在层
答: ARP 地址解析协议 数据接口层 通过IP地址获取地方的mac地址
RARP 逆向地址解析协议 通过mac地址获取IP地址
HTTP 超文本传输协议 应用层
IP 网际互连协议 网络层
TCP 传输控制协议 传输层
⑧ 100.0.125.2对应的默认子网掩码是多少
A类网 255.0.0.0
⑨ 顺序表和链表的区别
顺序表存储数据,需要预先申请一片足够大的内存空间,然后将数据按次序逐一存储,数据之间
紧密贴合,不留一丝空隙(物理地址连续)
链表的存储方式和顺序表截然相反,什么时候存储,什么时候才申请存储空间,数据之间的物理地址不连续
数据之间的逻辑关系依靠每个数据元素携带的指针维持连续。举个例子,就像医院里叫号
开辟空间的方式不同
顺序表存储数据实行的是 "一次开辟,永久使用",即存储数据之前先开辟好足够的存储空间,
空间一旦开辟后期无法改变大小(使用动态数组的情况除外)。
而链表则不同,链表存储数据时一次只开辟存储一个节点的物理空间,如果后期需要还可以再申请。
因此,若只从开辟空间方式的角度去考虑,当存储数据的个数无法提前确定,
又或是物理空间使用紧张以致无法一次性申请到足够大小的空间时,使用链表更有助于问题的解决。
空间利用率
从空间利用率的角度上看,顺序表的空间利用率显然要比链表高。
这是因为,链表在存储数据时,每次只申请一个节点的空间,且空间的位置是随机的
链表结构易产生碎片
这种申请存储空间的方式会产生很多空间碎片,一定程序上造成了空间浪费。
不仅如此,由于链表中每个数据元素都必须携带至少一个指针,因此使用顺序表访问元素的时间复杂度为
,链表对所申请空间的利用率也没有顺序表高。
空间碎片,指的是某些容量很小(1KB 甚至更小)以致无法得到有效利用的物理空间。
时间复杂度
解决不同类型的问题,顺序表和链表对应的时间复杂度也不同。
根据顺序表和链表在存储结构上的差异,问题类型主要分为以下 2 类:
① 问题中主要涉及访问元素的操作,元素的插入、删除和移动操作极少;
② 问题中主要涉及元素的插入、删除和移动,访问元素的需求很少;
第 1 类问题适合使用顺序表。这是因为,顺序表中存储的元素可以使用数组下标直接访问,
无需遍历整个表,因此使用顺序表访问元素的时间复杂度为 O(1);而在链表中访问数据元素,
需要从表头依次遍历,直到找到指定节点,花费的时间复杂度为 O(n);
第 2 类问题则适合使用链表。链表中数据元素之间的逻辑关系靠的是节点之间的指针,
当需要在链表中某处插入或删除节点时,只需改变相应节点的指针指向即可,无需大量移动元素,
因此链表中插入、删除或移动数据所耗费的时间复杂度为 O(1);
而顺序表中,插入、删除和移动数据可能会牵涉到大量元素的整体移动,因此时间复杂度至少为 O(n);
综上所述,不同类型的场景,选择合适的存储结构会使解决问题效率成倍数地提高。
⑩ 进程和线程的区别
线程(Thread) 与进程的概念(最本质)区别
1、进程 是操作系统分配资源的基本单位(最小单位)。
2、线程 是操作系统能够进行运算调度的最小单位。
三、进程和线程的区别与联系
(一)区别:
1、从属关系不同:线程属于进程,而进程不属于线程。
2、描述的侧重点不同:进程是系统分配资源的最小单位,而线程是系统调度的最小单位。
3、共享资源的方式不同:进程之间是不能共享资源的,线程之间可以共享资源(内存、打开的文件)
4、上下切换的速度不同:线程上下文切换的速度是比较快的,而进程的上下文切换比较慢。
5、操纵对象是不同的:进程是由操作系统操纵的,而线程是由程序员可以编码进行操纵的。
(二)联系:
1、线程被包含在进程之中,一个线程指的是进程中一个单一顺序的控制流,
一个线程只能属于一个进程,而一个进程可以并发多个(至少有一个)线程,
每条线程并行执行不同的任务。
2、资源分配给进程,同一进程的所有线程共享该进程的所有资源。
同一进程中的多个线程共享代码段(代码和常量),数据段(全局变量和静态变量),
扩展段(堆存储)。但是每个线程拥有自己的栈段,栈段又叫运行时段,用来存放所有局部变量和临时变量。
3、线程在执行过程中,需要协作同步。不同进程的线程间要利用消息通信的办法实现同步。
4、在Unix System V 及SunOS中线程也被称为轻量进程,但轻量进程更多指内核线程,
而把用户线程称为进程。
————————————————