同步、异步、阻塞、非阻塞

同步异步的概念与消息的通知机制有关,阻塞非阻塞的概念与等待消息通知时的状态有关。

 

同步异步是针对应用程序和内核的交互而言的。举个例子:当进程触发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”,直到有数据过来,循环停止。

转载于:https://www.cnblogs.com/sensal/p/5481442.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值