梁越

同步异步阻塞非阻塞详解

0 人看过

附c++代码

同步和异步

同步就是一个调用方发出请求开始,就一直处于等待状态,等待请求结果返回后才能继续执行其他任务。比如说调用一个函数,等待函数结果返回,这叫同步。

相反的,异步就是,调用该函数后,不等待函数结果返回,比如说开一个线程,让函数在线程运行,这叫异步。

阻塞和非阻塞

对于阻塞和非阻塞,其实更关心的是进程的状态,如果函数返回结果之前,主进程被挂起,也就是处于阻塞状态,那这时候整个过程是阻塞的;如果结果返回之前,主进程状态是非阻塞的,那整个过程是非阻塞。

举个例子

同步与异步:

你打电话问书店老板有没有《分布式系统》这本书,如果是同步通信机制,书店老板会说,你稍等,”我查一下”,然后开始查啊查,等查好了(可能是5秒,也可能是一天)告诉你结果(返回结果)。而异步通信机制,书店老板直接告诉你我查一下啊,查好了打电话给你,然后直接挂电话了(不返回结果)。然后查好了,他会主动打电话给你。在这里老板通过“回电”这种方式来回调。

这时候关心的是你是否在等待结果,有没有不管这件事

阻塞与非阻塞:

你打电话问书店老板有没有《分布式系统》这本书,你如果是阻塞式调用,你会一直把自己“挂起”,直到得到这本书有没有的结果,如果是非阻塞式调用,你不管老板有没有告诉你,你自己先一边去玩了, 当然你也要偶尔过几分钟check一下老板有没有返回结果。在这里阻塞与非阻塞与是否同步异步无关。跟老板通过什么方式回答你结果无关。

这时候关心的是你是否立即有答复,你是否离开了书店

c++ socket阻塞与非阻塞代码

阻塞模式下的socket读取

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 : %s\n", buf);

        /* 模拟 阻塞 处理过程 */
        sleep(10);        

        strcpy(buf, "Hello Client");
        res = write(fd, buf, sizeof(buf));
        printf("send data : %s\n", buf);
    }
}

非阻塞模式下的socket读取

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 : read\n");
                exit(1);
            }

        } else if (res == 0) {
            printf("\nclient closed the socket\n");
            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%E6%A8%A1%E5%BC%8F%E8%AF%A6%E8%A7%A3/

参考的解释:

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