异步编程举例之闹钟程序

 

本次主要和大家分享两个闹钟程序。它们分别是同步版本、多进程版本,之后和大家分享多线程版本。

该程序循环接受用户的输入信息,直到出错或者输入完毕。用户输入的信息第一部分是闹钟等待时间(以秒为单位),第二部分是闹钟时间到达后所显示的信息。

 

一 同步版本

创建Qt控制台程序,由于闹钟程序是c语言的,需要包含如下2个头文件。第一个是标准io的头文件,第二个是sleep()函数用到的头文件。接下来上码。

 

#include <QCoreApplication>

#include <stdio.h>

#include <unistd.h>

 

int main(int argc, char *argv[])

{

    QCoreApplication a(argc, argv);

 

    int seconds;

    char line[128];

    char message[64];

 

    while (1) {

        printf ("Alarm> ");

        if (fgets (line, sizeof (line), stdin) == NULL) exit (0);

        if (strlen (line) <= 1) continue;

 

        if (sscanf (line, "%d %64[^\n]",&seconds, message) < 2)

{

fprintf (stderr, "Bad command\n");

        } else {

            sleep (seconds);

            printf ("(%d) %s\n", seconds, message);

        }

    }

    return a.exec();

}

 

程序过程:

fgets(), c语言函数,程序中是从标准输入流读取并存储到line中,当读取(n-1)个字符、或读取到换行符时,或到达文件末尾时则停止。程序中如果读取结果为NULL,则程序退出。(出错或者到达文件尾部)如果读取长度不大于1,比如直接按下Enter键,则重新循环。

sscanf(), 从字符串中读取与指定格式相符的数据,成功时返回参数数目,失败返回-1。程序中是解析line中的字符串,将秒数解析到seconds中,显示信息解析到message中。集合操作 %64[^\n]——%64表示最大取64个字节,[^\n]匹配非\n的任意字符,贪婪性。即不要换行符,最多读64个字节。

成功解析字符串后,延时、打印信息。

缺点:一次只能处理一个闹钟请求。实际上是把希望用异步方式实现的工作用同步方式实现了。

 

二 多进程版本

有多种异步实现该程序的方法。其中一种方式是为每个命令使用fork调用生成一个子进程。这样可以随时输入命令行,彼此独立运行,不会阻塞等待。程序难点在于对子进程的资源回收,不做重点说明。

上码:

 

 

#include <QCoreApplication>

#include <stdio.h>

#include <unistd.h>

#include <sys/types.h>

#include <wait.h>

 

int main(int argc, char *argv[])

{

    QCoreApplication a(argc, argv);

 

    char line[128];

    int seconds;

    pid_t pid;

    char message[64];

 

    while (1) {

        printf ("Alarm> ");

        if (fgets (line, sizeof (line), stdin) == NULL) exit (0);

        if (strlen (line) <= 1) continue;

 

        if (sscanf (line, "%d %64[^\n]",

                    &seconds, message) < 2) {

            fprintf (stderr, "Bad command\n");

        } else {

            pid = fork ();

            if (pid == (pid_t)-1)

                printf("faild\n");

            if (pid == (pid_t)0) {

 

                sleep (seconds);

                printf ("(%d) %s\n", seconds, message);

                exit (0);

            } else {

 

                do {

                    pid = waitpid ((pid_t)-1, NULL, WNOHANG);

                    if (pid == (pid_t)-1)

                        printf("Wait for child\n");

                } while (pid != (pid_t)0);

            }

        }

    }

 

    return a.exec();

}

 

程序说明:

pid_t 对应头文件#include <sys/types.h>,waitpid函数对应#include <wait.h>头文件。

成功解析输入信息后,创建子进程延时、显示信息。父进程则等待子进程结束并回收资源,通常是调用某个waitpid函数。

WNOHANG属性使父进程不必挂起等待子进程结束。如果有子进程终止,则waitpid ()函数回收子进程资源,如果没有子进程结束,该函数立即返回0。父进程继续回收终止的子进程直到没有子进程终止。

 

程序运行结果如图:

 

欢迎大家在公众号中交流!

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值