zoukankan      html  css  js  c++  java
  • posix thread概述(示例代码)

    一个简单的alarm实例

    errors.h头文件

     1 #ifndef __ERRORS_H
     2 #define __ERORRS_H
     3 
     4 #include<stdio.h>
     5 #include<unistd.h>
     6 #include<errno.h>
     7 #include<stdlib.h>
     8 #include<string.h>
     9 
    10 #ifdef DEBUG
    11 #define DPRINTF(arg) printf arg
    12 #else
    13 #define DPRINTF(arg)
    14 #endif
    15 
    16 #define err_abort(code, text) do { 
    17     fprintf(stderr, "%s at "%s":%d: %s
    ", 
    18             text, __FILE__, __LINE__, strerror(code)); 
    19     abort(); 
    20 } while(0)
    21 
    22 #define errno_abort(text) do { 
    23     fprintf(stderr, "%s at "%s":%d: %s
    ", 
    24             text, __FILE__, __LINE__, strerror(errno));
    25     abort();
    26 }while(0)
    27 
    28 #endif
    errors.h

    普通实现:alarm.c

     1 #include"errors.h"
     2 
     3 /* alarm的普通实现 */
     4 int main(int argc, char* argv[])
     5 {
     6     int seconds;
     7     char line[128];
     8     char message[64];
     9 
    10     while(1)
    11     {
    12         printf("Alarm> ");
    13         if(fgets(line, sizeof(line), stdin) == NULL ) exit(0);
    14         if(strlen(line) <= 1 ) continue;
    15         if(sscanf(line, "%d %64[^
    ]", &seconds, message) < 2 )
    16             fprintf(stderr, "Bad command
    ");
    17         else
    18         {
    19             sleep(seconds);
    20             printf("(%d) %s
    ", seconds, message);
    21         }
    22 
    23     }
    24 }
    alarm.c

    多进程实现:alarm_fork.c

     1 #include "errors.h"
     2 #include<sys/types.h>
     3 #include<wait.h>
     4 
     5 /* alarm的多进程实现 */
     6 int main(int argc, char* argv[])
     7 {
     8     int status;
     9     char line[128];
    10     int seconds;
    11     pid_t pid;
    12     char message[64];
    13 
    14     while(1)
    15     {
    16         printf("Alarm> ");
    17         if(fgets(line, sizeof(line), stdin) == NULL ) exit(0);
    18         if(strlen(line) <= 1) continue;
    19         if(sscanf(line, "%d %64[^
    ]",
    20                     &seconds, message) < 2)
    21         {
    22             fprintf(stderr, "Bad command
    ");
    23         }
    24         else
    25         {
    26             pid = fork();
    27             if(pid == (pid_t)-1)
    28                 errno_abort("fork");
    29             if(pid == (pid_t)0)
    30             {
    31                 sleep(seconds);
    32                 printf("(%d) %s
    ", seconds, message);
    33                 exit(0);
    34             }
    35             else
    36             {
    37                 do
    38                 {
    39                     pid = waitpid((pid_t)-1, NULL, WNOHANG);
    40                     if(pid == (pid_t)-1)
    41                         errno_abort("wait child");
    42                 }while(pid != (pid_t)0);
    43             }
    44         }
    45     }
    46 }
    alarm_fork.c

    多线程实现:alarm_thread.c

     1 #include<pthread.h>
     2 #include "errors.h"
     3 
     4 /* alarm的多线程实现 */
     5 
     6 typedef struct alarm_tag {
     7     int seconds;
     8     char message[64];
     9 } alarm_t;
    10 
    11 void * alarm_thread(void *arg)
    12 {
    13     alarm_t *alarm = (alarm_t*)arg;
    14     int status;
    15 
    16     status = pthread_detach(pthread_self());
    17     if( status != 0 )
    18         err_abort(status, "pthread_detach");
    19     sleep(alarm->seconds);
    20     printf("(%d) %s
    ", alarm->seconds, alarm->message);
    21     free(alarm);
    22     return NULL;
    23 }
    24 
    25 int main(int argc, char* argv[])
    26 {
    27     int status;
    28     char line[128];
    29     alarm_t *alarm;
    30     pthread_t thread;
    31 
    32     while(1)
    33     {
    34         printf("Alarm> ");
    35         if(fgets(line, sizeof(line), stdin ) == NULL ) exit(0);
    36         if(strlen(line) <= 1) continue;
    37         alarm = (alarm_t*)malloc(sizeof(alarm_t));
    38         if( alarm == NULL )
    39             errno_abort("malloc");
    40         if( sscanf(line, "%d %64[^
    ]",
    41                     &alarm->seconds, alarm->message) < 2)
    42         {
    43             fprintf(stderr, "Bad command
    ");
    44             free(alarm);
    45         }
    46         else
    47         {
    48             status = pthread_create(&thread, NULL, alarm_thread, alarm);
    49             if( status != 0)
    50                 err_abort(status, "pthread_creat");
    51         }
    52     }
    53 }
    alarm_thread.c

    在以上alarm_thread.c代码执行时候,发现如果输入正好是128-1的倍数,将会出现Bad Command的提示。

    追究下原因,原来是fgets导致:

    fgets() reads in at most one less than size characters from stream and stores them into the buffer pointed to by s. Reading stops after an EOF or

    a newline. If a newline is read, it is stored into the buffer. A terminating null byte ('') is stored after the last character in the buffer.

     1 #include<stdio.h>
     2 #include<unistd.h>
     3 #include<error.h>
     4 #include<stdlib.h>
     5 
     6 void main(void)
     7 {
     8     char line[4];
     9     char* message;
    10 
    11     while(1)
    12     {
    13         printf("INPUT> ");
    14         if(fgets(line, sizeof(line), stdin ) == NULL ) exit(0);
    15         message = (char*)malloc(8);
    16         if( sscanf(line, "%2[^
    ]",
    17                     message) < 1)
    18         {
    19             fprintf(stderr, "sscanf error.
    ");
    20         }
    21         else
    22         {
    23             printf("message: %s
    ", message);
    24         }
    25         free(message);
    26     }
    27 }
    28 
    29 /* 
    30  *root@jdu-virtual-machine:~# ./a.out 
    31  *INPUT> aaa
    32  *message: aa
    33  *sscanf error.
    34  *INPUT> INPUT> ^C
    35  */
    Breakpoint 1 at 0x4007ca: file test.c, line 15.
    (gdb) r
    Starting program: /root/a.out 
    INPUT> aaa
    
    Breakpoint 1, main () at test.c:15
    15            message = (char*)malloc(8);
    (gdb) p line
    $1 = "aaa"
    (gdb) n
    16            if( sscanf(line, "%2[^
    ]",
    (gdb) 
    23                printf("message: %s
    ", message);
    (gdb) p message
    $2 = 0x602010 "aa"
    (gdb) n
    message: aa
    25            free(message);
    (gdb) 
    26        }
    (gdb) 
    13            printf("INPUT> ");
    (gdb) 
    14            if(fgets(line, sizeof(line), stdin ) == NULL ) exit(0);
    (gdb) 
    
    Breakpoint 1, main () at test.c:15
    15            message = (char*)malloc(8);
    (gdb) p line
    $3 = "
    00a"
    (gdb) n
    16            if( sscanf(line, "%2[^
    ]",
    (gdb) 
    19                fprintf(stderr, "sscanf error.
    ");
    (gdb) 
    sscanf error.
    25            free(message);
    (gdb) 
  • 相关阅读:
    [日常] Go语言圣经-命令行参数
    [日常] Go语言圣经前言
    [日常] 搭建golang开发环境
    [日常] 研究redis未授权访问漏洞利用过程
    [日常] CentOS安装最新版redis设置远程连接密码
    [日常] Apache Order Deny,Allow的用法
    [日常] 读取队列并循环发信的脚本
    [日常] 20号日常工作总结
    [日常] SinaMail项目和技术能力总结
    [日常] MySQL的预处理技术测试
  • 原文地址:https://www.cnblogs.com/licongyu/p/5032024.html
Copyright © 2011-2022 走看看