标签:
同步异步是针对应用程序和内核的交互而言的。举个例子:当进程触发IO操作后,
同步:进程需要自己来确定什么时候IO操作完成,进程自己需要不断的查询来确定任务是否完成。(期间进程可以去做其他事)
异步:进程不需要自己确定什么时候IO操作完成,当任务完成后,内核会通知该进程。
阻塞:进程停止在当前操作,不进行后面的操作;直到当前操作完成。(阻塞是指当前操作的运行模式)
非阻塞:进程不停止在当前操作,当前操作会立即返回一个结果,然后进行后面的操作。(非阻塞是指当前操作的运行模式)
同步阻塞:进程停止在当前操作,期间进程不断查询当前操作是否完成。
同步非阻塞:进程不停止在当前操作A,执行后面的其他操作B...,但期间不断的查询操作A是否完成。
异步阻塞:进程停止在当前操作A,并不执行后面的操作,等操作A完成后,内核通知进程,进程再执行后面的操作。
异步非阻塞:进程不停止在当前操作A,转而去执行后面的操作,操作A完成后,内核通知进程操作A执行完成。
对于非阻塞而言:如果操作A还没完成,但是当前进程已经执行完成,进程会停下来等待操作A完成吗?在等待的这段时间进程又是什么状态呢?
对于非阻塞而言,操作A会立即返回结果。
下面用网络中的recvfrom来具体介绍阻塞与非阻塞的区别。
对于network IO而言,它涉及到两个对象,内核和调用IO的进程,一般划分为两个阶段:
1、等待数据准备(Waiting for the data to be ready)
2、将数据从内核拷贝到进程(Copying the data from the kernel to the process)
阻塞IO模式:
非阻塞模式:
异步模式:
用一个udp客户端服务端的程序来解释一下同步阻塞与同步非阻塞的区别:(其客户端是一样的,主要区别是服务端)
客户端:
#include <stdio.h> #include <string.h> #include <sys/socket.h> #include <netinet/in.h> int main(int argc, char **argv) { int sockfd; struct sockaddr_in servaddr; sockfd = socket(PF_INET, SOCK_DGRAM, 0); bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(50001); servaddr.sin_addr.s_addr = inet_addr("127.0.0.1"); char sendline[100]; sprintf(sendline, "Hello, world!"); sendto(sockfd, sendline, strlen(sendline), 0, (struct sockaddr *)&servaddr, sizeof(servaddr)); close(sockfd); return 1; }
服务端阻塞:
#include <stdio.h> #include <string.h> #include <sys/socket.h> #include <netinet/in.h> int main(int argc, char **argv) { int sockfd; struct sockaddr_in servaddr; sockfd = socket(PF_INET, SOCK_DGRAM, 0); bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_port = htons(50001); bind(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)); int n; char recvline[1024]; recvfrom(sockfd, recvline, 1024, 0, NULL, NULL); printf("%s\n", recvline); close(sockfd); }
服务端非阻塞:
#include <stdio.h> #include <string.h> #include <sys/socket.h> #include <netinet/in.h> int main(int argc, char **argv) { int sockfd; struct sockaddr_in servaddr; sockfd = socket(PF_INET, SOCK_DGRAM, 0); bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_port = htons(50001); bind(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)); int n; char recvline[1024]; int result = recvfrom(sockfd, recvline, 1024, MSG_DONTWAIT, NULL, NULL); while(result != -1){ result = recvfrom(sockfd, recvline, 1024, MSG_DONTWAIT, NULL, NULL); printf("continue recvfrom"); } printf("%s\n", recvline); close(sockfd); }
在阻塞模式中,服务端会一直等待数据,不会执行下面的操作。
在非阻塞模式中,服务端会立即返回结果,在此例子中,没有接受到的数据,就返回-1,因此在非阻塞模式中会一直服务端会一直输出“continue recvfrom”,直到有数据过来,循环停止。
标签:
原文地址:http://www.cnblogs.com/sensal/p/5481442.html