码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2016-05-11 13:33:09      阅读:238      评论:0      收藏:0      [点我收藏+]

标签:

同步异步是针对应用程序和内核的交互而言的。举个例子:当进程触发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

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!