Welcome 微信登录
编程资源 图片资源库 蚂蚁家优选 PDF转换器

首页 / 操作系统 / Linux / 深入Linux网络编程(一):同步IO

1. IO模型

IO分为同步、异步,阻塞、非阻塞,两两组合成4种模型。

2. 同步阻塞IO

2.1 阻塞的原因

一个常见的问题是IO对请求没有准备好:例如调用读请求的时候可能设备上没有数据,但是将来可能有;调用写请求时可能舍妹没有准备好接收数据,一会儿可能buffer清空就好了。调用过程一般不去理会这些问题,如果程序员仅仅要求在请求返回时工作做好,那么驱动设备就应该阻塞这个请求的进程,使他陷入睡眠状态。

2.2 什么是睡眠

当一个进程处于睡眠态, 意味着它被移除调度队列,直到这个状态被改变之前,CPU都不会处理这个进程。有几个注意事项:
  • 不要在原子上下文中sleep
  • 无法保证精确的睡眠时间
  • 只有在确定其他进程/内核会唤醒自己时,才能睡眠

2.3 同步阻塞IO的编程模型

3. 同步阻塞IO的网络编程代码示例

/* A simple server in the internet domain using TCP The port number is passed as an argument */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <sys/types.h> #include <sys/socket.h>#include <netinet/in.h>void error(const char *msg){perror(msg);exit(1);}int main(int argc, char *argv[]){ int sockfd, newsockfd, portno; socklen_t clilen; char buffer[256]; struct sockaddr_in serv_addr, cli_addr; int n; if (argc < 2) { fprintf(stderr,"ERROR, no port provided "); exit(1); } sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) error("ERROR opening socket"); bzero((char *) &serv_addr, sizeof(serv_addr)); portno = atoi(argv[1]); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = INADDR_ANY; serv_addr.sin_port = htons(portno); if (bind(sockfd, (struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0) error("ERROR on binding"); listen(sockfd,5); clilen = sizeof(cli_addr); newsockfd = accept(sockfd,(struct sockaddr *) &cli_addr,&clilen); if (newsockfd < 0) error("ERROR on accept"); bzero(buffer,256); n = read(newsockfd,buffer,255); if (n < 0) error("ERROR reading from socket"); printf("Here is the message: %s ",buffer); n = write(newsockfd,"I got your message",18); if (n < 0) error("ERROR writing to socket"); close(newsockfd); close(sockfd); return 0; }