| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 4163 人关注过本帖
标题:关于C语言同步调用,回调,异步调用
只看楼主 加入收藏
lv740542742
Rank: 1
等 级:新手上路
帖 子:10
专家分:7
注 册:2015-9-9
结帖率:0
收藏
已结贴  问题点数:10 回复次数:15 
关于C语言同步调用,回调,异步调用
最近在看C语言异步调用方面的知识

同步调用也称之为堵塞式调用,就是调用方必须等被调用方执行完毕并返回值后才接着执行,这个比较好理解。
回调 很多资料上说 回调是一种双向调用模式,也就是说,被调用方在接口被调用时也会调用对方的接口;我的理解是通过把一个函数的地址作为形参给调用函数,简单说就是用一个函数去调用另外一个函数。都说回调是非堵塞式调用,但我觉得这也是同步调用,调用函数也是必须等被调用函数执行完才能接着执行。
//Test.c  
#include <stdlib.h>  
#include <stdio.h>  
int Test1()  
{  
    int i;  
    for (i=0; i<30; i++)  
    {  
        printf("The %d th charactor is: %c\n", i, (char)('a' + i%26));  
         
    }  
    return 0;  
}  
int Test2(int num)  
{  
    int i;  
    for (i=0; i<num; i++)  
    {  
        printf("The %d th charactor is: %c\n", i, (char)('a' + i%26));  
         
    }  
    return 0;  
}  
void Caller1(void (*ptr)())//指向函数的指针作函数参数  
{  
    (*ptr)();  
    do other something;
}  
void Caller2(int n, int (*ptr)())//指向函数的指针作函数参数,这里第一个参数是为指向函数的指针服务的,  
{   //不能写成void Caller2(int (*ptr)(int n));这样的定义语法错误。  
    (*ptr)(n);  
    do other something;
    return;  
}  
int main()  
{  
    printf("************************\n");  
    Caller1(Test1); //相当于调用Test2();  
    printf("&&&&&&************************\n");  
    Caller2(30, Test2); //相当于调用Test2(30);  
    return 0;  
}


异步调用更困惑了,资料上说异步调用是一种类似消息或事件的机制,不过它的调用方向刚好相反,接口的服务在收到某种讯息或发生某种事件时,会主动通知客户方(即调用客户方的接口)。我的理解是被调用方反过来去通知调用方,具体怎么实现的呢,能不能举个例子说明
搜索更多相关主题的帖子: 知识 接口 C语言 include 资料 
2015-09-09 13:44
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:528
帖 子:9007
专家分:53942
注 册:2011-1-18
收藏
得分:0 
都说回调是非堵塞式调用
回调 和 是否塞式调用 之间没有任何关系
前者是一种接口,后者是一种时序
2015-09-09 14:11
lv740542742
Rank: 1
等 级:新手上路
帖 子:10
专家分:7
注 册:2015-9-9
收藏
得分:0 
回复 2楼 rjsp
大神,能否举一个异步调用的例子?我想明白到底怎么实现的
2015-09-09 14:31
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:528
帖 子:9007
专家分:53942
注 册:2011-1-18
收藏
得分:0 
要想异步,最起码你得开个线程呀
因为我的glic还没有<threads.h>,因此我用C++替代(C++仅限于线程这一部分,其它尽量遵循C习惯)
程序代码:
#include <stdio.h>
#include <thread>

int thrdfun( void* arg )
{
    for( size_t i=0; i!=30; ++i )
        putchar( '1' );
    return 0;
}

int main( void )
{
    std::thread t( thrdfun, nullptr );

    for( size_t i=0; i!=30; ++i )
        putchar( '0' );

    t.join();
    return 0;
}
main函数连续输出30个'0',thrdfun函数连续输出30个'1'。
一种可能的输出是 101010101110010110010010001010010110010011001010010100111111
之所以说“可能的输出”,是因为main的执行和thrdfun的执行是异步的。
2015-09-09 15:02
lv740542742
Rank: 1
等 级:新手上路
帖 子:10
专家分:7
注 册:2015-9-9
收藏
得分:0 
回复 4楼 rjsp
谢谢 虽然不是很懂。。怎么用回调来实现异步调用呢?
2015-09-09 15:21
zklhp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:china
等 级:贵宾
威 望:254
帖 子:11485
专家分:33241
注 册:2007-7-10
收藏
得分:2 
以下是引用rjsp在2015-9-9 15:02:17的发言:

要想异步,最起码你得开个线程呀
因为我的glic还没有,因此我用C++替代(C++仅限于线程这一部分,其它尽量遵循C习惯)
#include  
#include  
 
int thrdfun( void* arg )
{
    for( size_t i=0; i!=30; ++i )
        putchar( '1' );
    return 0;
}
 
int main( void )
{
    std::thread t( thrdfun, nullptr );
 
    for( size_t i=0; i!=30; ++i )
        putchar( '0' );
 
    t.join();
    return 0;
}main函数连续输出30个'0',thrdfun函数连续输出30个'1'。
一种可能的输出是 101010101110010110010010001010010110010011001010010100111111
之所以说“可能的输出”,是因为main的执行和thrdfun的执行是异步的。

我写一个纯C的 用到了pthread posix的线程函数

程序代码:
// gcc -Wall -std=c11 a.c -o a
#include <pthread.h>
#include <stdio.h>

void *Print(void *threadid)
{
    for (size_t i = 0; i != 30; ++i)
    {
        sleep(1);
        putchar('0');
    }
    pthread_exit(NULL);
}

int main(void)
{
    pthread_t thread;
    int rc;
    rc = pthread_create(&thread, NULL, Print, NULL);
    if (rc)
    {
        printf("ERROR; return code from pthread_create() is %d\n", rc);
        exit(-1);
    }
   
    for (size_t i = 0; i != 30; ++i)
    {
        sleep(1);
        putchar('1');
       
    }
    pthread_join(thread, NULL);

    /* Last thing that main() should do */
    pthread_exit(NULL);
}


第一次写 献丑了
2015-09-09 18:31
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:528
帖 子:9007
专家分:53942
注 册:2011-1-18
收藏
得分:2 
回复 6楼 zklhp
棒,还是pthread用的人多
2015-09-09 19:35
实际应用
Rank: 5Rank: 5
等 级:职业侠客
威 望:2
帖 子:89
专家分:341
注 册:2015-5-30
收藏
得分:2 
看的出楼主读了很多东西,很佩服

楼主的例子是同步的
异步的也很多,比如画面上的各种控件对应的处理就是一种回调
在程序里给那个控件发一个事件,就是异步处理

另外一个例子,
在程序里加上这个,就可在内存错时回调,异步的
signal( SIGSEGV, callback )

2015-09-09 22:44
小王KING
Rank: 2
等 级:论坛游民
威 望:1
帖 子:29
专家分:69
注 册:2015-9-9
收藏
得分:0 
2楼说的很对,要举个例子很麻烦,写出来你未必看的明白,就说说吧
要实现异步回调,这就出现了多线程问题,但是在C语言在是作用于DOS系统下
DOS系统没有多线程的概念,但是有中断的概念
就是利用中断来实现你的异步回调,BOIS中断里有一个叫时钟中断的程序,这个时钟中断程序它是一直运行的
你只要自己写个中断函数,然后把你写的这个中断函数接管那个时钟中断程序,这样你写的这个中断函数就能一直不停的运行了
DOS下的异步回调就是利用时钟中断来实现的

[ 本帖最后由 小王KING 于 2015-9-10 01:13 编辑 ]
2015-09-10 01:00
Yang201511
Rank: 2
等 级:论坛游民
帖 子:5
专家分:24
注 册:2015-9-9
收藏
得分:2 
回复 楼主 lv740542742
C的标准库中没有线程库,我这里用的是 Windows API函数演示

图片附件: 游客没有浏览图片的权限,请 登录注册
2015-09-10 08:25
快速回复:关于C语言同步调用,回调,异步调用
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.017411 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved