一个简单的alarm实例

errors.h头文件

 #ifndef __ERRORS_H
#define __ERORRS_H #include<stdio.h>
#include<unistd.h>
#include<errno.h>
#include<stdlib.h>
#include<string.h> #ifdef DEBUG
#define DPRINTF(arg) printf arg
#else
#define DPRINTF(arg)
#endif #define err_abort(code, text) do { \
fprintf(stderr, "%s at \"%s\":%d: %s\n", \
text, __FILE__, __LINE__, strerror(code)); \
abort(); \
} while() #define errno_abort(text) do { \
fprintf(stderr, "%s at \"%s\":%d: %s\n", \
text, __FILE__, __LINE__, strerror(errno));\
abort();\
}while() #endif

errors.h

普通实现:alarm.c

 #include"errors.h"

 /* alarm的普通实现 */
int main(int argc, char* argv[])
{
int seconds;
char line[];
char message[]; while()
{
printf("Alarm> ");
if(fgets(line, sizeof(line), stdin) == NULL ) exit();
if(strlen(line) <= ) continue;
if(sscanf(line, "%d %64[^\n]", &seconds, message) < )
fprintf(stderr, "Bad command\n");
else
{
sleep(seconds);
printf("(%d) %s\n", seconds, message);
} }
}

alarm.c

多进程实现:alarm_fork.c

 #include "errors.h"
#include<sys/types.h>
#include<wait.h> /* alarm的多进程实现 */
int main(int argc, char* argv[])
{
int status;
char line[];
int seconds;
pid_t pid;
char message[]; while()
{
printf("Alarm> ");
if(fgets(line, sizeof(line), stdin) == NULL ) exit();
if(strlen(line) <= ) continue;
if(sscanf(line, "%d %64[^\n]",
&seconds, message) < )
{
fprintf(stderr, "Bad command\n");
}
else
{
pid = fork();
if(pid == (pid_t)-)
errno_abort("fork");
if(pid == (pid_t))
{
sleep(seconds);
printf("(%d) %s\n", seconds, message);
exit();
}
else
{
do
{
pid = waitpid((pid_t)-, NULL, WNOHANG);
if(pid == (pid_t)-)
errno_abort("wait child");
}while(pid != (pid_t));
}
}
}
}

alarm_fork.c

多线程实现:alarm_thread.c

 #include<pthread.h>
#include "errors.h" /* alarm的多线程实现 */ typedef struct alarm_tag {
int seconds;
char message[];
} alarm_t; void * alarm_thread(void *arg)
{
alarm_t *alarm = (alarm_t*)arg;
int status; status = pthread_detach(pthread_self());
if( status != )
err_abort(status, "pthread_detach");
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[];
alarm_t *alarm;
pthread_t thread; while()
{
printf("Alarm> ");
if(fgets(line, sizeof(line), stdin ) == NULL ) exit();
if(strlen(line) <= ) continue;
alarm = (alarm_t*)malloc(sizeof(alarm_t));
if( alarm == NULL )
errno_abort("malloc");
if( 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( status != )
err_abort(status, "pthread_creat");
}
}
}

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.

 #include<stdio.h>
#include<unistd.h>
#include<error.h>
#include<stdlib.h> void main(void)
{
char line[];
char* message; while()
{
printf("INPUT> ");
if(fgets(line, sizeof(line), stdin ) == NULL ) exit();
message = (char*)malloc();
if( sscanf(line, "%2[^\n]",
message) < )
{
fprintf(stderr, "sscanf error.\n");
}
else
{
printf("message: %s\n", message);
}
free(message);
}
} /*
*root@jdu-virtual-machine:~# ./a.out
*INPUT> aaa
*message: aa
*sscanf error.
*INPUT> INPUT> ^C
*/
Breakpoint  at 0x4007ca: file test.c, line .
(gdb) r
Starting program: /root/a.out
INPUT> aaa Breakpoint , main () at test.c:
message = (char*)malloc();
(gdb) p line
$1 = "aaa"
(gdb) n
if( sscanf(line, "%2[^\n]",
(gdb)
printf("message: %s\n", message);
(gdb) p message
$2 = 0x602010 "aa"
(gdb) n
message: aa
free(message);
(gdb)
}
(gdb)
printf("INPUT> ");
(gdb)
if(fgets(line, sizeof(line), stdin ) == NULL ) exit();
(gdb) Breakpoint , main () at test.c:
message = (char*)malloc();
(gdb) p line
$
3 = "\n\000a"
(gdb) n
if( sscanf(line, "%2[^\n]",
(gdb)
fprintf(stderr, "sscanf error.\n");
(gdb)
sscanf error.
free(message);
(gdb)

posix thread概述(示例代码)的更多相关文章

  1. posix thread概述

    1. 基本概念 一个Unix进程可以理解为一个线程加上地址空间.文件描述符和其他数据.异步表明事情相互独立发生, 除非有强加的依赖性. 并发指实际可能是穿行发生的事情好像同时发生一样.并行指并发序列同 ...

  2. C/C++ 开源库及示例代码

    C/C++ 开源库及示例代码 Table of Contents 说明 1 综合性的库 2 数据结构 & 算法 2.1 容器 2.1.1 标准容器 2.1.2 Lockfree 的容器 2.1 ...

  3. 0038 Java学习笔记-多线程-传统线程间通信、Condition、阻塞队列、《疯狂Java讲义 第三版》进程间通信示例代码存在的一个问题

    调用同步锁的wait().notify().notifyAll()进行线程通信 看这个经典的存取款问题,要求两个线程存款,两个线程取款,账户里有余额的时候只能取款,没余额的时候只能存款,存取款金额相同 ...

  4. ActiveMQ笔记(1):编译、安装、示例代码

    一.编译 虽然ActiveMQ提供了发布版本,但是建议同学们自己下载源代码编译,以后万一有坑,还可以尝试自己改改源码. 1.1 https://github.com/apache/activemq/r ...

  5. redis 学习笔记(2)-client端示例代码

    redis提供了几乎所有主流语言的client,java中主要使用二种:Jedis与Redisson 一.Jedis的使用 <dependency> <groupId>redi ...

  6. posix thread 浅谈

    用Posix thread进行多线程设计,就不怕跨平台了,因为很多OS都兼容Posix thread,如Linux/Windows等,甚至嵌入式系统上(如rt-thread)都支持posix thre ...

  7. python开源项目及示例代码

    本页面是俺收集的各种 Python 资源,不定期更新. 下面列出的各种 Python 库/模块/工具,如果名称带超链接,说明是第三方的:否则是 Python 语言内置的. 1 算法 1.1 字符串处理 ...

  8. java 添加一个线程、创建响应的用户界面 。 演示示例代码

    javajava 添加一个线程.创建响应的用户界面 . 演示示例代码 来自thinking in java 4 21章  部分的代码  夹21.2.11 thinking in java 4免费下载: ...

  9. python开源项目及示例代码(转)

    本页面是俺收集的各种 Python 资源,不定期更新. 下面列出的各种 Python 库/模块/工具,如果名称带超链接,说明是第三方的:否则是 Python 语言内置的. 1 算法 1.1 字符串处理 ...

随机推荐

  1. HDU 1495 非常可乐 BFS搜索

    题意:有个为三个杯子(杯子没有刻度),体积为s,n,m,s=m+n, 刚开始只有体积为s的杯子装满可乐,可以互相倒,问你最少的次数使可乐均分,如果没有结果,输出-1; 分析:直接互相倒就完了,BFS模 ...

  2. Oracle学习网址

    Oracle Error Search: http://www.ora-error.com/ Oracle Database Error Message - Oracle Documentation: ...

  3. 配置OpenGL及第一个实例

    Windows环境下安装GLUT的步骤:1.将下载的压缩包解开,将得到5个文件2.在“我的电脑”中搜索“gl.h”,并找到其所在文件夹(如果是VS,则应该是其安装目录下面的“VC\PlatformSD ...

  4. Flash AIR14导出ipa到Mac上的iOS模拟器测试

    没错!你没看错!俺这篇博客就是关于Flash AIR的! ----------------无聊的分割线------------------ 朋友最近学习Flash AIR for iOS开发,想找我帮 ...

  5. 用户名 不在 sudoers文件中,此事将被报告。

    原文解决方法:http://blog.csdn.net/lincyang/article/details/21020295 CentOS7.0 用到sudo权限的时候出现的问题,如题. sudo命令可 ...

  6. 【暑假】[实用数据结构]UVa11997 K Smallest Sums

    UVa11997 K Smallest Sums  题目: K Smallest Sums You're given k arrays, each array has k integers. Ther ...

  7. Clean Code – Chapter 2: Meaningful Names

    Use Intention-Revealing Names The name should tell you why it exists, what it does, and how it is us ...

  8. 对Map按key和value分别排序

    一.理论准备         Map是键值对的集合接口,它的实现类主要包括:HashMap,TreeMap,Hashtable以及LinkedHashMap等.         TreeMap:基于红 ...

  9. mysql修改字段的语句写法

    http://www.111cn.net/database/mysql/50678.htm 下面为您介绍的sql语句都是mysql修改字段操作中的一些常用语句,如果您是一个刚刚接触mysql数据库的新 ...

  10. Umbraco中Document Type取名限制

    在Umbraco中,每一个Document type都会被ModelsBuilder生成一个class,但是,有些developers发现,当你把一些Document Type命名为Grid, Pro ...