同步和异步例子(linux)

来源:互联网 发布:安卓优化软件 编辑:程序博客网 时间:2024/06/16 07:45

《POSIX多线程程序设计》——David R.Buten

同步

alarm.c

#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>int main(int argc, char *argv[]) {    int seconds;    char line[128];    char message[64];    while (1) {        printf("Alarm> ");        if (NULL == fgets(line, sizeof(line), stdin)) exit(0);        if (1 >= strlen(line)) continue;        if (2 > sscanf(line, "%d %64[^\n]", &seconds, message))            fprintf(stderr, "Bad command\n");        else {            sleep(seconds);            printf("(%d) %s\n", seconds, message);        }    }    return 0;}

gcc -o alarm alarm.c
这里写图片描述

局限性:一次只能处理一个闹钟请求。

异步(多进程)

alarm_fork.c

#include <errno.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <wait.h>#include <sys/types.h>#define errno_abort(text) do { \    fprintf(stderr, "%s at \"%s\":%d: %s\n", \        text, __FILE__, __LINE__, strerror(errno)); \    abort(); \    } while (0)int main(int argc, char *argv[]) {    int status;    char line[128];    int seconds;    pid_t pid;    char message[64];    while (1) {        printf("Alarm> ");        if (NULL == fgets(line, sizeof(line), stdin)) exit(0);        if (1 >= strlen(line)) continue;        if (2 > sscanf(line, "%d %64[^\n]", &seconds, message))            fprintf(stderr, "Bad command\n");        else {            pid = fork();            if ((pid_t)-1 == pid) // failure                errno_abort("Fork");             if ((pid_t)0 == pid) { // child                 sleep(seconds);                printf("(%d) %s\n", seconds, message);                exit(0);            }            else { // parent                do {                            pid = waitpid((pid_t)-1, NULL, WNOHANG); // 非阻塞等待子进程结束,回收子进程                    //printf("#%d\n", pid);                                     if ((pid_t)-1 == pid)                        errno_abort("Wait for child");                } while ((pid_t)0 != pid);            }        }    }       return 0;}

gcc -o alarm_fork alarm_fork.c
2
alarm_fork.c中的main函数没有直接调用sleep函数 ,而是创建了一个子进程,在子进程中异步地调用sleep函数和printf,而父进程则继续运行。

调用waitpid函数回收子进程,并设置WNOHANG(父进程不必挂起等待子进程的结束)。

异步(多线程)

alarm_thread.c

#include <errno.h>#include <pthread.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#define err_abort(code, text) do { \    fprintf(stderr, "%s at \"%s\":%d: %s\n", \        text, __FILE__, __LINE__, strerror(errno)); \    abort(); \    } while (0)#define errno_abort(text) do { \    fprintf(stderr, "%s at \"%s\":%d: %s\n", \        text, __FILE__, __LINE__, strerror(errno)); \    abort(); \    } while (0)typedef struct alarm_tag {    int seconds;    char message[64];} alarm_t;void* alarm_thread(void *arg) {    alarm_t *alarm = (alarm_t *)arg;    int status;    status = pthread_detach(pthread_self()); // 分离自己,在它终止后立刻回收    if (0 != status)         err_abort(status, "Detach thread");    sleep(alarm->seconds);    printf("(%d) %s\n", alarm->seconds, alarm->message);    free(alarm);    return NULL;}int main(int argc, char *argv[]) {    int status;    char line[128];    alarm_t *alarm;    pthread_t thread;    while (1) {        printf("Alarm> ");        if (NULL == fgets(line, sizeof(line), stdin)) exit(0);        if (1 >= strlen(line)) continue;        alarm = (alarm_t *)malloc(sizeof(alarm_t));        if (NULL == alarm)            errno_abort("Allocate alarm");        if (2 > sscanf(line, "%d %64[^\n]", &alarm->seconds, alarm->message)) {            fprintf(stderr, "Bad command\n");            free(alarm);        }           else {            status = pthread_create(&thread, NULL, alarm_thread, alarm);            if (0 != status)                err_abort(status, "Create alarm thread");        }    }    return 0;}

gcc -o alarm_thread alarm_thread.c -lpthread
3

0 0
原创粉丝点击