一个简单的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概述(示例代码)的更多相关文章
-
posix thread概述
1. 基本概念 一个Unix进程可以理解为一个线程加上地址空间.文件描述符和其他数据.异步表明事情相互独立发生, 除非有强加的依赖性. 并发指实际可能是穿行发生的事情好像同时发生一样.并行指并发序列同 ...
-
C/C++ 开源库及示例代码
C/C++ 开源库及示例代码 Table of Contents 说明 1 综合性的库 2 数据结构 & 算法 2.1 容器 2.1.1 标准容器 2.1.2 Lockfree 的容器 2.1 ...
-
0038 Java学习笔记-多线程-传统线程间通信、Condition、阻塞队列、《疯狂Java讲义 第三版》进程间通信示例代码存在的一个问题
调用同步锁的wait().notify().notifyAll()进行线程通信 看这个经典的存取款问题,要求两个线程存款,两个线程取款,账户里有余额的时候只能取款,没余额的时候只能存款,存取款金额相同 ...
-
ActiveMQ笔记(1):编译、安装、示例代码
一.编译 虽然ActiveMQ提供了发布版本,但是建议同学们自己下载源代码编译,以后万一有坑,还可以尝试自己改改源码. 1.1 https://github.com/apache/activemq/r ...
-
redis 学习笔记(2)-client端示例代码
redis提供了几乎所有主流语言的client,java中主要使用二种:Jedis与Redisson 一.Jedis的使用 <dependency> <groupId>redi ...
-
posix thread 浅谈
用Posix thread进行多线程设计,就不怕跨平台了,因为很多OS都兼容Posix thread,如Linux/Windows等,甚至嵌入式系统上(如rt-thread)都支持posix thre ...
-
python开源项目及示例代码
本页面是俺收集的各种 Python 资源,不定期更新. 下面列出的各种 Python 库/模块/工具,如果名称带超链接,说明是第三方的:否则是 Python 语言内置的. 1 算法 1.1 字符串处理 ...
-
java 添加一个线程、创建响应的用户界面 。 演示示例代码
javajava 添加一个线程.创建响应的用户界面 . 演示示例代码 来自thinking in java 4 21章 部分的代码 夹21.2.11 thinking in java 4免费下载: ...
-
python开源项目及示例代码(转)
本页面是俺收集的各种 Python 资源,不定期更新. 下面列出的各种 Python 库/模块/工具,如果名称带超链接,说明是第三方的:否则是 Python 语言内置的. 1 算法 1.1 字符串处理 ...
随机推荐
-
奇妙的CSS之布局与定位
前言 关于布局与定位是Web前端开发里非常基础而又重要的部分.介绍相关知识的文章,很容易就可以找到.虽然,这方面的知识点不是很多,但我们如果不弄清楚,在运用时候往往会出现预料之外的布局,这些“意外”有 ...
-
VBA常用函数
字符串相关: ①截取字符串: 从字符串左侧开始:Left(string,length) 从字符串右侧开始:Right(string,length) 从字符串中间开始:mid(string,start, ...
-
JAVA生成图片缩略图、JAVA截取图片局部内容
package com.ares.image.test; import java.awt.Color; import java.awt.Graphics; import java.awt.Image; ...
-
完成了第一个java
这是我的第一个java程序,求水仙花数2016-04-26 22:39:09
-
各浏览器各版本User-agent汇总 欢迎补充
Internet Explorer Internet Explorer 5 Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; WOW64; Trident/ ...
-
ASP.NET SignalR2持久连接层解析
越是到年底越是感觉浑身无力,看着啥也不想动,只期盼着年终奖的到来以此来给自己打一针强心剂.估摸着大多数人都跟我一样犯着这样浑身无力的病,感觉今年算是没挣到啥钱,但是话也不能这么说,搞得好像去年挣到钱了 ...
-
替换bmp图片中的颜色 good
工作中,经常需要将bmp图片中的某个颜色修改为另外一种颜色.比如:将图片中的所有白色均修改成灰色. 平时都是拿画图板中的油漆桶工具一点一点的刷,费时又费力.(这么干好几年了 :( ) 今天抽空编了一个 ...
-
ssh常用用法小结
ssh常用用法小结 1.连接到远程主机: 命令格式 : ssh name@remoteserver 或者 ssh remoteserver -l name 说明:以上两种方式都可以远程登录到远程主机, ...
-
腾讯.NET面试题
在整个面试过程中,作为面试者的你,角色就是小怪兽,面试官的角色则是奥特曼,更不幸的是,作为小怪兽的你是孤身一人,而奥特曼却往往有好几个~ 以下是网友发的关于腾讯的.NET面试题,不得不说还是有一定的难 ...
-
Qt websocket
1.pro 添加 QT += websockets #ifndef MYWEBSOCKETSERVER_H #define MYWEBSOCKETSERVER_H #include <QObj ...