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\n", \
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\n", \
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[^\n]", &seconds, message) < 2 )
16             fprintf(stderr, "Bad command\n");
17         else
18         {
19             sleep(seconds);
20             printf("(%d) %s\n", 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[^\n]",
20                     &seconds, message) < 2)
21         {
22             fprintf(stderr, "Bad command\n");
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\n", 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\n", 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[^\n]",
41                     &alarm->seconds, alarm->message) < 2)
42         {
43             fprintf(stderr, "Bad command\n");
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 ('\0') 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[^\n]",
17                     message) < 1)
18         {
19             fprintf(stderr, "sscanf error.\n");
20         }
21         else
22         {
23             printf("message: %s\n", 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[^\n]",
(gdb) 
23                printf("message: %s\n", 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 = "\n\000a"
(gdb) n
16            if( sscanf(line, "%2[^\n]",
(gdb) 
19                fprintf(stderr, "sscanf error.\n");
(gdb) 
sscanf error.
25            free(message);
(gdb) 

 

posted @ 2015-12-09 10:23  弋痕夕的残影  阅读(458)  评论(0编辑  收藏  举报