一个简单的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. [MySQL-1] mysql error 1101 blob/text column can't have a default value

    在MySQL Query Browser上创建一个含有TEXT类型的字段,创建不成功,报错:mysql error 1101 blob/text column can't have a default ...

  2. 430单片机之定时器A功能的大致介绍

    总的来说,430单片机一共有三个定时器,定时器A,定时器B,还有就是看门狗定时器,这里我们主要是讨论430单片机的定时器A的功能,定时器A的功能是我目前见过最厉害的定时器,视频上说用好定时器A的话,对 ...

  3. SQLBulkCopy使用

    SQLBulkCopy,用于数据库之间大批量的数据传递.通常用于新,旧数据库之间数据的更新.即使表结构完全不同,也可以通过字段间的对应关系,顺利的将数据导过来. 首先,SQLBulkCopy需要2个连 ...

  4. 【译】 AWK教程指南 11递归程序

    awk 中除了函数的参数列表(Argument List)上的参数(Arguments)外,所有变量不管于何处出现,全被视为全局变量.其生命持续至程序结束——该变量不论在function外或 func ...

  5. Gym 100827G Number Game (博弈)

    Number Game Alice and Bob are playing a game on a line of N squares. The line is initially populated ...

  6. 应用web框架模块设计三国演义篇--转至微博

    从事web开发已经10年时间,近几年也一直从事微博应用产品的研发.从原生php写网站到使用cms bbs整合的大型站点,从使用各种流行的开源开发框架到成熟稳定的平台级框架下做研发.这期间对应用型web ...

  7. Oracle-PLSQL Developer使用笔记

    1.新建菜单 command window ---->命令行,执行sql语句 sql window ---->执行sql语句,可导出CSV,TSV,HTML,XML等类型文件 report ...

  8. [css]inline-block

    能被父容器居中.能设置高度宽度和margin.不会像table或div那样占一正行……——这就是inline-block——记得这是浏览器默认样式告诉你的.

  9. Jenkins 实际项目操作

    .Abstract { padding: 15px; border: dotted 2px #999; color: #999; font-family: "Microsoft Yahei& ...

  10. Oracle- 包

    在一个大型项目中,可能有很多模块,而每个模块又有自己的过程.函数等.而这些过程.函数默认是放在一起的(如在PL/SQL中,过程默认都是放在一起的,即Procedures中),这些非常不方便查询和维护. ...