一个简单的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. POJ 1236 Network of Schools 有向图强连通分量

    参考这篇博客: http://blog.csdn.net/ascii991/article/details/7466278 #include <stdio.h> #include < ...

  2. vector(相对线程安全) arryList(线程不安全)

    1.什么是线程安全? 如果说某个集合是线程安全的,那么我们就不用考虑并发访问这个集合?(需要定义自己百度,但是很难懂) 2.深入jvm中的线程安全的级别. a不变模式(String等基本类型) b.绝 ...

  3. 卡特兰数 BZOJ3907 网格 NOIP2003 栈

    卡特兰数 卡特兰数2 卡特兰数:主要是求排列组合问题 1:括号化矩阵连乘,问多少种方案 2:走方格,不能过对角线,问多少种方案 3:凸边型,划分成三角形 4:1到n的序列进栈,有多少种出栈方案 NOI ...

  4. HDU 4714 Tree2cycle

    Tree2cycle dfs 不是根节点:如果边数大于等于2,则删除与父节点的边.并且是一条环,那么每个点的度数是2,则还要删除num(每个节点儿子数)-2,只留两个儿子.当然删除边的儿子也要连到环上 ...

  5. dynamic调用时报RuntimeBinderException:“object”未包含“xxx”的定义 错误

    情况如下:两个项目项目A命名空间 Test.PA   匿名类型所在 项目B命名空间 Test.PB 在Test.PB 中通过dynamic关键字调用Test.PA中匿名类型时报上述错误 解决办法 在项 ...

  6. 百度oauth2.0 WEB 链接

    Source:http://developer.baidu.com/wiki/index.php?title=docs/oauth/authorization Webpage Function : A ...

  7. poll()

    # include < sys/ poll. h> int poll ( struct pollfd * fds, unsigned int nfds, int timeout) ; 和s ...

  8. web开发工具类

    1.日期工具类 import java.text.SimpleDateFormat; import java.util.Date; public class DateUtil { public sta ...

  9. Microsoft .NET Pet Shop 4

    Microsoft .NET Pet Shop 4:将 ASP.NET 1.1 应用程序迁移到 2.0 299(共 313)对本文的评价是有帮助 - 评价此主题 发布日期 : 2006-5-9 | 更 ...

  10. 剑指OFFER之数组中出现次数超过一半的数字(九度OJ1370)

    题目描述: 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2 ...