附c 代码
同步和异步
同步就是一个调用方发出请求开始,就一直处于等待状态,等待请求结果返回后才能继续执行其他任务。比如说调用一个函数,等待函数结果返回,这叫同步。
相反的,异步就是,调用该函数后,不等待函数结果返回,比如说开一个线程,让函数在线程运行,这叫异步。
阻塞和非阻塞
对于阻塞和非阻塞,其实更关心的是进程的状态,如果函数返回结果之前,主进程被挂起,也就是处于阻塞状态,那这时候整个过程是阻塞的;如果结果返回之前,主进程状态是非阻塞的,那整个过程是非阻塞。
举个例子
同步与异步:
你打电话问书店老板有没有《分布式系统》这本书,如果是同步通信机制,书店老板会说,你稍等,”我查一下”,然后开始查啊查,等查好了(可能是5秒,也可能是一天)告诉你结果(返回结果)。而异步通信机制,书店老板直接告诉你我查一下啊,查好了打电话给你,然后直接挂电话了(不返回结果)。然后查好了,他会主动打电话给你。在这里老板通过“回电”这种方式来回调。
这时候关心的是你是否在等待结果,有没有不管这件事
阻塞与非阻塞:
你打电话问书店老板有没有《分布式系统》这本书,你如果是阻塞式调用,你会一直把自己“挂起”,直到得到这本书有没有的结果,如果是非阻塞式调用,你不管老板有没有告诉你,你自己先一边去玩了, 当然你也要偶尔过几分钟check一下老板有没有返回结果。在这里阻塞与非阻塞与是否同步异步无关。跟老板通过什么方式回答你结果无关。
这时候关心的是你是否立即有答复,你是否离开了书店
c socket阻塞与非阻塞代码
阻塞模式下的socket读取
代码语言:javascript复制int main(){
#创建和绑定socket,creat和bind函数
#aceept监听
#等待数据
while (1) {
int len = sizeof(struct sockaddr);
fd = accept(sfd, &remote, &len);
res = read(fd, buf, sizeof(buf));
printf("user data : %sn", buf);
/* 模拟 阻塞 处理过程 */
sleep(10);
strcpy(buf, "Hello Client");
res = write(fd, buf, sizeof(buf));
printf("send data : %sn", buf);
}
}
非阻塞模式下的socket读取
代码语言:javascript复制int main(){
#创建和绑定socket,creat和bind函数
#设置socket为non-block,使用fcntl函数
#创建epoll,检测event
#aceept监听
#等待数据
while (1) {
memset(buf, 0, BUF_SIZE);
res = read(events[i].data.fd, buf, BUF_SIZE);
if (res == -1) {
if (errno == EAGAIN) {
break;
} else {
perror("ERROR : readn");
exit(1);
}
} else if (res == 0) {
printf("nclient closed the socketn");
close(events[i].data.fd);
break;
} else {
//printf("%s", buf);
//fflush(stdout);
write(STDOUT_FILENO, buf, res);
}
}
}
详细代码参考:https://github.com/spch2008/Socket/blob/master/
IO模式
下一篇将详细介绍IO模式:https://www.openrad.ink/2021/03/09/IO模式详解/
参考的解释:
https://leetcode-cn.com/circle/discuss/uHGOZo/
https://www.zhihu.com/question/19732473
https://blog.csdn.net/datuzijean/article/details/90520902
https://www.cnblogs.com/loveer/p/11479249.html#962752061
https://github.com/spch2008/Socket/blob/master/tcp/alarmall/alarmsrv.c