apue 02 管道 定时器
2014-01-05 19:29
162 查看
1. 从文件中读取数据写入FIFO
2. 从FIFO中读数据然后写入文件
3.计算管道PIPE的大小
4.使用读写stdin,stdout重定位实现文件的拷贝
5.管道概念
1.管道
·本质有固定大小的内核缓冲区
·特点:
@半双工 单向
@只能用于有共同祖先的进程通信
·#include <unistd.h>
int pipe(int fd[2])
·fd[1] 写端
·fd[0] 读端
2.当管道满的时候
O_NONBLOCK disable: write调用阻塞 即进程暂停执行 一直等到有数据来到为止
O_NONBLOCK enable: 返回-1 EAGAIN 调用返回-1 errno值为EAGAIN
3.当管道满时
如果是阻塞的则write()函数调用阻塞 知道有进程读走数据
如果为非阻塞 调用-1 errno 值为EAGAIN
4.如果写或读有关闭的
read 返回0 write会产生SIGPIPE信号
5.当写入的数据小于PIPE_BUF(4K) linux将保证写入的原子性 否则不保证
6.匿名管道有限制就是需要共同的祖先进程才能通信
命名管道FIFO不需要 用于不相关的进程通信 是一种特殊类型的文件
如果有度或写一个未打开 则默认会阻塞操作会阻塞
6. 非阻塞管道的读写
7.管道的简单读写
8.时间的函数
sleep
usleep
9.定时器的使用 alarm()
alarm()可以产生SIGALARM信号
setitimer() 间歇性的产生SIGALARM信号
10. setitimer() getitimer() 设置定时器
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <errno.h> #include <fcntl.h> #define ERR_EXIT(m) \ do \ { \ perror(m); \ exit(EXIT_FAILURE); \ } while(0) #define TEST_SIZE 68*1024 int main(void) { mkfifo("tp", 0644); int infd; infd = open("test.txt", O_RDONLY); if (infd == -1) ERR_EXIT("open"); int outfd; outfd = open("tp", O_WRONLY); if (outfd == -1) ERR_EXIT("open"); char buf[1024]; int n; while ((n=read(infd, buf, 1024))>0) { write(outfd, buf, n); } close(infd); close(outfd); return 0; }
2. 从FIFO中读数据然后写入文件
#include <unistd.h> #include <sys/stat.h> #include <sys/wait.h> #include <sys/types.h> #include <fcntl.h> #include <stdlib.h> #include <stdio.h> #include <errno.h> #include <string.h> #include <signal.h> #include <sys/time.h> #define ERR_EXIT(m) \ do \ { \ perror(m); \ exit(EXIT_FAILURE); \ } while(0) int main(int argc, char *argv[]) { int outfd; outfd = open("t.txt", O_WRONLY | O_CREAT | O_TRUNC, 0644); if (outfd == -1) ERR_EXIT("open"); int infd; infd = open("tp", O_RDONLY); if (outfd == -1) ERR_EXIT("open"); char buf[1024]; int n; while ((n=read(infd, buf, 1024))>0) { write(outfd, buf, n); } close(infd); close(outfd); unlink("tp"); return 0; }
3.计算管道PIPE的大小
#include <unistd.h> #include <sys/stat.h> #include <sys/wait.h> #include <sys/types.h> #include <fcntl.h> #include <stdlib.h> #include <stdio.h> #include <errno.h> #include <string.h> #include <signal.h> #define ERR_EXIT(m) \ do \ { \ perror(m); \ exit(EXIT_FAILURE); \ } while(0) void handler(int sig) { printf("%d\n",sig); } int main(int argc, char *argv[]) { int pipefd[2]; if(-1 ==pipe(pipefd)) ERR_EXIT("pipe error"); //使用fcntl通过文件描述符来设置文件的属性 int flags = fcntl(pipefd[1], F_GETFL); flags |= O_NONBLOCK; fcntl(pipefd[1], F_SETFL, flags); int ret; int count = 0; while(1) { ret = write(pipefd[1], "A", 1); // 一直写直到阻塞 if(-1 == ret) { printf("err=%s", strerror(errno)); break; } ++count; } printf("count=%d\n", count); return 0; }
4.使用读写stdin,stdout重定位实现文件的拷贝
#include <unistd.h> #include <sys/stat.h> #include <sys/wait.h> #include <sys/types.h> #include <fcntl.h> #include <stdlib.h> #include <stdio.h> #include <errno.h> #include <string.h> #include <signal.h> #define ERR_EXIT(m) \ do \ { \ perror(m); \ exit(EXIT_FAILURE); \ } while(0) int main(int argc, char *argv[]) { // 这里进行了重定位 close(0); // 1. close stdin 关闭读端 使其指向 hello.c open("./hello.c", O_RDONLY); close(1); // 2. close stdout 关闭写端 使其指向 hello2.c open("./hello2.c", O_WRONLY | O_CREAT | O_TRUNC, 0644); execlp("cat", "cat", NULL); // 3. cat 不带参数时 将stdin标准输入拷贝到标准输出stdout 实现了文件的拷贝 return 0; }
5.管道概念
1.管道
·本质有固定大小的内核缓冲区
·特点:
@半双工 单向
@只能用于有共同祖先的进程通信
·#include <unistd.h>
int pipe(int fd[2])
·fd[1] 写端
·fd[0] 读端
2.当管道满的时候
O_NONBLOCK disable: write调用阻塞 即进程暂停执行 一直等到有数据来到为止
O_NONBLOCK enable: 返回-1 EAGAIN 调用返回-1 errno值为EAGAIN
3.当管道满时
如果是阻塞的则write()函数调用阻塞 知道有进程读走数据
如果为非阻塞 调用-1 errno 值为EAGAIN
4.如果写或读有关闭的
read 返回0 write会产生SIGPIPE信号
5.当写入的数据小于PIPE_BUF(4K) linux将保证写入的原子性 否则不保证
6.匿名管道有限制就是需要共同的祖先进程才能通信
命名管道FIFO不需要 用于不相关的进程通信 是一种特殊类型的文件
如果有度或写一个未打开 则默认会阻塞操作会阻塞
6. 非阻塞管道的读写
#include <unistd.h> #include <sys/stat.h> #include <sys/wait.h> #include <sys/types.h> #include <fcntl.h> #include <stdlib.h> #include <stdio.h> #include <errno.h> #include <string.h> #include <signal.h> #define ERR_EXIT(m) \ do \ { \ perror(m); \ exit(EXIT_FAILURE); \ } while(0) int main(int argc, char *argv[]) { int pipe_fd[2]; if(-1 == pipe(pipe_fd)) { ERR_EXIT("pipe error"); } pid_t pid; pid = fork(); if(-1 == pid) ERR_EXIT("pipe error"); if(0 == pid)//child process { sleep(3); close(pipe_fd[0]); // 这里子进程关闭的它的读端 因为拷贝后 父子进程分开了 write(pipe_fd[1], "hello pipe \n", 12); close(pipe_fd[1]); exit(EXIT_SUCCESS); } close(pipe_fd[1]); char buf[12] = {0}; //set nonblock int flags = fcntl(pipe_fd[0], F_GETFL); fcntl(pipe_fd[0], F_SETFL, flags | O_NONBLOCK); int ret =read(pipe_fd[0], buf, 12); if(-1 == ret ) ERR_EXIT("read error"); printf("read pipe == %s \n ", buf); return 0; }
7.管道的简单读写
#include <unistd.h> #include <sys/stat.h> #include <sys/wait.h> #include <sys/types.h> #include <fcntl.h> #include <stdlib.h> #include <stdio.h> #include <errno.h> #include <string.h> #include <signal.h> #define ERR_EXIT(m) \ do \ { \ perror(m); \ exit(EXIT_FAILURE); \ } while(0) int main(int argc, char *argv[]) { int pipe_fd[2]; if(-1 == pipe(pipe_fd)) { ERR_EXIT("pipe error"); } pid_t pid; pid = fork(); if(-1 == pid) ERR_EXIT("pipe error"); if(0 == pid)//child process { close(pipe_fd[0]); write(pipe_fd[1], "hello pipe \n", 12); close(pipe_fd[1]); exit(EXIT_SUCCESS); } close(pipe_fd[1]); char buf[12] = {0}; read(pipe_fd[0], buf, 12); printf("read pipe == %s", buf); return 0; }
8.时间的函数
sleep
·while(n = sleep(time))//返回剩余的秒数 ·do { n = sleep(n); }while(n>0)
usleep
nanosleep(const struct timespec* req, struc timespec *rem) struct timespec{ time_t tv_sec; /* seconds */ long tv_nsec; /* nanoseconds */ }; struct timeval{ long tv_sec; long tv_usec; };
9.定时器的使用 alarm()
alarm()可以产生SIGALARM信号
setitimer() 间歇性的产生SIGALARM信号
#include <sys/time.h> int getitimer(int which, struct itimerval *curr_value);//获取剩余的时间 剩余多久会产生信号 int setitimer(int which, const struct itimerval *new_value, struct itimerval *old_value); struct itimerval { struct timeval it_interval; /* next value */ struct timeval it_value; /* current value */ }; struct timeval { long tv_sec; /* seconds */ long tv_usec; /* microseconds */ };
10. setitimer() getitimer() 设置定时器
#include <unistd.h> #include <sys/stat.h> #include <sys/wait.h> #include <sys/types.h> #include <fcntl.h> #include <stdlib.h> #include <stdio.h> #include <errno.h> #include <string.h> #include <signal.h> #include <sys/time.h> #define ERR_EXIT(m) \ do \ { \ perror(m); \ exit(EXIT_FAILURE); \ } while(0) void handler(int sig) { printf("recv a sig=%d\n", sig); } int main(int argc, char *argv[]) { if (signal(SIGALRM, handler) == SIG_ERR) ERR_EXIT("signal error"); struct timeval tv_interval = {1, 0}; struct timeval tv_value = {5, 0}; struct itimerval itimev; itimev.it_interval = tv_interval; itimev.it_value = tv_value; setitimer(ITIMER_REAL, &itimev, NULL); int i; for (i=0; i<10000; i++); struct itimerval oit; setitimer(ITIMER_REAL, &itimev, &oit); getitimer(ITIMER_REAL, &itimev); // 得到剩余定时器的响应时间 printf("%d %d %d %d\n", (int)itimev.it_interval.tv_sec, \ (int)itimev.it_interval.tv_usec, (int)itimev.it_value.tv_sec, \ (int)itimev.it_value.tv_usec); for (;;) pause(); return 0; }
相关文章推荐
- 【Java多线程与并发库】02 传统定时器技术
- Linux06--Shell程序设计02 数据流重定向与管道
- 进程间通信_02匿名管道
- APUE读书笔记-17高级进程通信-02基于流的管道.txt
- 进程间通信机制02_管道
- Redis教程02——管道(Pipelining)
- 02_张孝祥_Java多线程_传统定时器Timer
- 02 AVR定时器的探索
- RT-Thread 02定时器
- [总结]IPC之管道
- [bbk5398] 第96集 -第12章 -数据移植 02
- mysql 创建定时器
- 定时器
- JAVA全集-02-基本语法
- kafka-02-集群搭建
- 软件定时器
- 内核定时器
- 「C++」条款02 & 03:#define & const
- 使用STM32定时器输出任意相位差的方波
- (原创)c#学习笔记08--面向对象编程简介02--OOP技术05--运算符重载