临汾网站建设价格,营销型网站能解决什么问题,wordpress镶嵌网页,百度关键词刷排名教程1#xff1a;五种IO模型 1#xff1a;阻塞IO 阻塞IO: 在内核将数据准备好之前,系统调用会一直等待.所有的套接字,默认 都是阻塞方式。 2#xff1a;非阻塞 IO 非阻塞 IO: 如果内核还未将数据准备好, 系统调用仍然会直接返回, 并且返回EWOULDBLOCK 错误码。 非阻塞 IO 往往需… 1五种IO模型 1阻塞IO 阻塞IO: 在内核将数据准备好之前,系统调用会一直等待.所有的套接字,默认 都是阻塞方式。 2非阻塞 IO 非阻塞 IO: 如果内核还未将数据准备好, 系统调用仍然会直接返回, 并且返回EWOULDBLOCK 错误码。 非阻塞 IO 往往需要循环的方式反复尝试读写文件描述符(对于CPU会有较大的浪费), 这个过程称为轮询。 3信号驱动IO 信号驱动 IO: 内核将数据准备好的时候, 使用 SIGIO 信号通知应用程序进行 IO操作。 4IO多路转接 IO 多路转接: 虽然从流程图上看起来和阻塞 IO 类似. 实际上最核心在于 IO 多路转接能够同时等待多个文件描述符的就绪状态。 5异步IO 异步 IO: 由内核在数据拷贝完成时, 通知应用程序(而信号驱动是告诉应用程序何时可以开始拷贝数据)。 2总结 任何 IO 过程中, 都包含两个步骤。 第一是等待, 第二是拷贝。而且在实际的应用场景中, 等待消耗的时间往往都远远高于拷贝的时间。让 IO 更高效, 最核心的办法就是让等待的时间尽量少。 同步通信(synchronous communication) vs 异步通信(asynchronous communication) 1. 同步(Synchronous IO) 就是在发出一个调用时 在没有得到结果之前 该调用就不返回。但是一旦调用返回 就得到返回值了; 换句话说 就是由调用者主动等待这个调用的结果; 2. 异步(Asynchronous IO) 调用在发出之后 这个调用就直接返回了 所以没有返回结果; 换句话说 当一个异步过程调用发出后 调用者不会立刻得到结果; 而是在调用发出后 被调用者通过状态、 通知来通知调用者 或通过回调函数处理这个调用。 同步Synchronizationvs 互斥Mutual Exclusion 同步Synchronization 同步是指在多线程环境中协调多个线程的执行顺序使得它们能够按照预定的顺序执行。同步通常用于确保线程之间的合作例如一个线程可能需要等待另一个线程完成某些任务后才能继续执行。同步可以通过多种机制实现如信号量Semaphore、事件Event、条件变量Condition Variable等。 互斥Mutual Exclusion 互斥是指在多线程环境中确保同一时间只有一个线程能够访问某个特定的资源或代码段。互斥主要用于防止竞争条件即多个线程同时访问和修改共享数据导致数据不一致的问题。互斥可以通过锁Locks如互斥锁Mutex、读写锁Read-Write Lock等来实现。
常见的同步和互斥机制
互斥锁Mutex一种基本的同步机制用于保护临界区确保同一时间只有一个线程可以进入临界区。信号量Semaphore用于控制对共享资源的访问可以允许多个线程同时访问也可以限制访问数量。事件Event用于线程之间的通信一个线程可以等待事件被另一个线程触发。条件变量Condition Variable用于线程之间的同步允许线程在某些条件不满足时挂起并在条件满足时被唤醒。读写锁Read-Write Lock允许多个读操作同时进行但写操作会独占锁确保写操作的互斥。
同步与互斥的区别
同步关注的是线程之间的协调和合作确保它们能够按照正确的顺序执行。互斥关注的是保护共享资源防止多个线程同时访问同一资源从而避免数据不一致。 阻塞Blockingvs 非阻塞Non-blocking 阻塞和非阻塞关注的是程序在等待调用结果消息 返回值 时的状态。 阻塞Blocking 当一个线程执行一个阻塞操作时它会停止执行直到该操作完成。在等待期间线程不会做任何其他工作。阻塞操作通常用于简化编程模型因为它们不需要额外的机制来处理并发和同步。缺点是阻塞操作可能导致程序的响应性降低特别是在等待时间较长的情况下。 非阻塞Non-blocking 非阻塞操作不会停止线程的执行。如果操作尚未完成线程可以继续执行其他任务。非阻塞操作通常需要额外的同步机制如事件、回调或轮询来处理操作的完成。优点是可以提高程序的并发性和响应性因为线程不需要等待就可以继续执行其他任务。
阻塞与非阻塞的比较 性能 阻塞操作可能导致线程资源的浪费特别是在IO密集型应用中。非阻塞操作可以提高资源利用率因为线程可以在等待期间执行其他任务。 编程复杂性 阻塞操作通常更容易理解和实现因为它们遵循同步编程模型。非阻塞操作可能更复杂需要更多的同步和错误处理机制。 适用场景 阻塞操作适用于简单的应用或那些不需要高并发的场景。非阻塞操作适用于需要高并发和快速响应的系统如服务器和网络应用。
实际应用中的阻塞与非阻塞 文件IO 阻塞式文件IO当一个线程读取文件时如果文件不可用线程会等待直到文件可用。非阻塞式文件IO线程会立即返回不会等待文件可用而是定期检查文件状态。 网络IO 阻塞式网络IO当一个线程等待数据到来时它会阻塞直到数据到达。非阻塞式网络IO线程会立即返回不会等待数据而是定期检查数据是否到达。 3非阻塞IO举例 fcntl #include unistd.h
#include fcntl.h
int fcntl(int fd, int cmd, ... /* arg */ ); 传入的 cmd 的值不同, 后面追加的参数也不相同。 fcntl 函数有 5 种功能 • 复制一个现有的描述符cmdF_DUPFD。 • 获得/设置文件描述符标记(cmdF_GETFD 或 F_SETFD)。 • 获得/设置文件状态标记(cmdF_GETFL 或 F_SETFL)。 • 获得/设置异步 I/O 所有权(cmdF_GETOWN 或 F_SETOWN)。 • 获得/设置记录锁(cmdF_GETLK,F_SETLK 或 F_SETLKW)。 轮询方式读取标准输入 #include iostream
#include unistd.h
#include fcntl.h
#include sys/select.hint SetNoBlock(int fd)
{int flags fcntl(fd, F_GETFL);if (flags -1){perror(fcntl get flags);return 0;}else{int n fcntl(fd, F_SETFL, flags | O_NONBLOCK);if (n -1){perror(fcntl set flags);return 0;}}return 1;
}int main()
{if (!SetNoBlock(0)){perror(fcntl set fcntl!);return -1;}while (true){printf(Enter: );fflush(stdout);char buffer[1024];ssize_t n ::read(0, buffer, sizeof(buffer));// 如果是非阻塞底层数据没有准备就绪IO接口会以出错的形式返回// 区分 底层不就绪 与 真的出错了 // 底层没有就绪错误码被设置errno错误码EWOULDBLOCK EAGAINif (n 0){buffer[n] 0;std::cout buffer std::endl;}else if (n 0) //ctrl d 读取输入结束{perror(read done);break;}else{if (errno EWOULDBLOCK){sleep(1);// 轮询检测...// Do other things...printf(Do other things\n);continue;}else if (errno EINTR) // 处理读取被中断{continue;}else{perror(read);break;}}sleep(1);}return 0;
}