- 浏览: 64272 次
- 性别:
- 来自: 苏州
文章分类
最新评论
-
brxonline:
提示不能这样写234390216 写道234390216 写道 ...
mysql导出数据为excel -
234390216:
234390216 写道不行啊,错误
提示不能这样写
mysql导出数据为excel -
234390216:
不行啊,错误
mysql导出数据为excel
. 管道
#include <unistd.h>
int pipe(int filedes[2]);
|
Returns: 0 if OK, 1 on error |
参数filedes返回两个文件描述符:filedes[0]为读而打开,filedes[1]为写而打开。
例:经由管道父进程向子进程传递数据
#include "apue.h" int main(void) { int n; int fd[2]; pid_t pid; char line[MAXLINE]; if (pipe(fd) < 0) err_sys("pipe error"); if ((pid = fork()) < 0) { err_sys("fork error"); } else if (pid > 0) { /* parent */ close(fd[0]); write(fd[1], "hello world\n", 12); } else { /* child */ close(fd[1]); n = read(fd[0], line, MAXLINE); write(STDOUT_FILENO, line, n); } exit(0); }
例:将文件复制到分页程序
#include "apue.h" #include <sys/wait.h> #define DEF_PAGER "/bin/more" /* default pager program */ int main(int argc, char *argv[]) { int n; int fd[2]; pid_t pid; char *pager, *argv0; char line[MAXLINE]; FILE *fp; if (argc != 2) err_quit("usage: a.out <pathname>"); if ((fp = fopen(argv[1], "r")) == NULL) err_sys("can't open %s", argv[1]); if (pipe(fd) < 0) err_sys("pipe error"); if ((pid = fork()) < 0) { err_sys("fork error"); } else if (pid > 0) { /* parent */ close(fd[0]); /* close read end */ /* parent copies argv[1] to pipe */ while (fgets(line, MAXLINE, fp) != NULL) { n = strlen(line); if (write(fd[1], line, n) != n) err_sys("write error to pipe"); } if (ferror(fp)) err_sys("fgets error"); close(fd[1]); /* close write end of pipe for reader */ if (waitpid(pid, NULL, 0) < 0) err_sys("waitpid error"); exit(0); } else { /* child */ close(fd[1]); /* close write end */ if (fd[0] != STDIN_FILENO) { if (dup2(fd[0], STDIN_FILENO) != STDIN_FILENO) err_sys("dup2 error to stdin"); close(fd[0]); /* don't need this after dup2 */ } /* get arguments for execl() */ if ((pager = getenv("PAGER")) == NULL) pager = DEF_PAGER; if ((argv0 = strrchr(pager, '/')) != NULL) argv0++; /* step past rightmost slash */ else argv0 = pager; /* no slash in pager */ if (execl(pager, argv0, (char *)0) < 0) err_sys("execl error for %s", pager); } exit(0); }
使父子进程同步的例程
#include "apue.h"
static int pfd1[2], pfd2[2];
void
TELL_WAIT(void)
{
if (pipe(pfd1) < 0 || pipe(pfd2) < 0)
err_sys("pipe error");
}
void
TELL_PARENT(pid_t pid)
{
if (write(pfd2[1], "c", 1) != 1)
err_sys("write error");
}
void
WAIT_PARENT(void)
{
char c;
if (read(pfd1[0], &c, 1) != 1)
err_sys("read error");
if (c != 'p')
err_quit("WAIT_PARENT: incorrect data");
}
void
TELL_CHILD(pid_t pid)
{
if (write(pfd1[1], "p", 1) != 1)
err_sys("write error");
}
void
WAIT_CHILD(void)
{
char c;
if (read(pfd2[0], &c, 1) != 1)
err_sys("read error");
if (c != 'c')
err_quit("WAIT_CHILD: incorrect data");
}
2.popen和pclose函数
#include <stdio.h> FILE *popen(const char *cmdstring, const char *type);
|
Returns: file pointer if OK, NULL on error |
int pclose(FILE *fp);
|
Returns: termination status of cmdstring, or 1 on error |
例:用popen向分页程序传递文件
#include "apue.h" #include <sys/wait.h> #define PAGER "${PAGER:-more}" /* environment variable, or default */ int main(int argc, char *argv[]) { char line[MAXLINE]; FILE *fpin, *fpout; if (argc != 2) err_quit("usage: a.out <pathname>"); if ((fpin = fopen(argv[1], "r")) == NULL) err_sys("can't open %s", argv[1]); if ((fpout = popen(PAGER, "w")) == NULL) err_sys("popen error"); /* copy argv[1] to pager */ while (fgets(line, MAXLINE, fpin) != NULL) { if (fputs(line, fpout) == EOF) err_sys("fputs error to pipe"); } if (ferror(fpin)) err_sys("fgets error"); if (pclose(fpout) == -1) err_sys("pclose error"); exit(0); }
大小写过滤程序
#include "apue.h" #include <ctype.h> int main(void) { int c; while ((c = getchar()) != EOF) { if (isupper(c)) c = tolower(c); if (putchar(c) == EOF) err_sys("output error"); if (c == '\n') fflush(stdout); } exit(0); }
#include "apue.h" #include <sys/wait.h> int main(void) { char line[MAXLINE]; FILE *fpin; if ((fpin = popen("myuclc", "r")) == NULL) err_sys("popen error"); for ( ; ; ) { fputs("prompt> ", stdout); fflush(stdout); if (fgets(line, MAXLINE, fpin) == NULL) /* read from pipe */ break; if (fputs(line, stdout) == EOF) err_sys("fputs error to pipe"); } if (pclose(fpin) == -1) err_sys("pclose error"); putchar('\n'); exit(0); }
3.协同进程
对两个数求和的简单过滤程序
#include "apue.h" int main(void) { int n, int1, int2; char line[MAXLINE]; while ((n = read(STDIN_FILENO, line, MAXLINE)) > 0) { line[n] = 0; /* null terminate */ if (sscanf(line, "%d%d", &int1, &int2) == 2) { sprintf(line, "%d\n", int1 + int2); n = strlen(line); if (write(STDOUT_FILENO, line, n) != n) err_sys("write error"); } else { if (write(STDOUT_FILENO, "invalid args\n", 13) != 13) err_sys("write error"); } } exit(0); }
include "apue.h"
static void sig_pipe(int); /* our signal handler */
int
main(void)
{
int n, fd1[2], fd2[2];
pid_t pid;
char line[MAXLINE];
if (signal(SIGPIPE, sig_pipe) == SIG_ERR)
err_sys("signal error");
if (pipe(fd1) < 0 || pipe(fd2) < 0)
err_sys("pipe error");
if ((pid = fork()) < 0) {
err_sys("fork error");
} else if (pid > 0) { /* parent */
close(fd1[0]);
close(fd2[1]);
while (fgets(line, MAXLINE, stdin) != NULL) {
n = strlen(line);
if (write(fd1[1], line, n) != n)
err_sys("write error to pipe");
if ((n = read(fd2[0], line, MAXLINE)) < 0)
err_sys("read error from pipe");
if (n == 0) {
err_msg("child closed pipe");
break;
}
line[n] = 0; /* null terminate */
if (fputs(line, stdout) == EOF)
err_sys("fputs error");
}
if (ferror(stdin))
err_sys("fgets error on stdin");
exit(0);
} else { /* child */
close(fd1[1]);
close(fd2[0]);
if (fd1[0] != STDIN_FILENO) {
if (dup2(fd1[0], STDIN_FILENO) != STDIN_FILENO)
err_sys("dup2 error to stdin");
close(fd1[0]);
}
if (fd2[1] != STDOUT_FILENO) {
if (dup2(fd2[1], STDOUT_FILENO) != STDOUT_FILENO)
err_sys("dup2 error to stdout");
close(fd2[1]);
}
if (execl("./add2", "add2", (char *)0) < 0)
err_sys("execl error");
}
exit(0);
}
static void
sig_pipe(int signo)
{
printf("SIGPIPE caught\n");
exit(1);
}
4.FIFO
#include <sys/stat.h> int mkfifo(const char *pathname, mode_t mode);
|
Returns: 0 if OK, 1 on error |
5.XSI IPC
消息队列,信号量,共享存储称作XSI IPC
1)标识符和键
标识符是IPC对象的内部名
键是IPC对象的外部名
2)权限结构
XSI IPC 为每一个IPC结构设置了一个ipc_perm结构
struct ipc_perm {
uid_t uid; /* owner's effective user id */
gid_t gid; /* owner's effective group id */
uid_t cuid; /* creator's effective user id */
gid_t cgid; /* creator's effective group id */
mode_t mode; /* access modes */
.
.
.
};
6.消息队列
每个队列都有一个msq_ds与其相关联
struct msqid_ds {
struct ipc_perm msg_perm; /* see Section 15.6.2 */
msgqnum_t msg_qnum; /* # of messages on queue */
msglen_t msg_qbytes; /* max # of bytes on queue */
pid_t msg_lspid; /* pid of last msgsnd() */
pid_t msg_lrpid; /* pid of last msgrcv() */
time_t msg_stime; /* last-msgsnd() time */
time_t msg_rtime; /* last-msgrcv() time */
time_t msg_ctime; /* last-change time */
.
.
.
};
#include <sys/msg.h> int msgget(key_t key, int flag);
|
Returns: message queue ID if OK, 1 on error |
#include <sys/msg.h> int msgctl(int msqid, int cmd, struct msqid_ds *buf );
|
Returns: 0 if OK, 1 on error |
#include <sys/msg.h> int msgsnd(int msqid, const void *ptr, size_t nbytes, int flag);
|
Returns: 0 if OK, 1 on error |
#include <sys/msg.h> ssize_t msgrcv(int msqid, void *ptr, size_t nbytes , long type, int flag);
|
Returns: size of data portion of message if OK, 1 on error |
7.信号量
struct semid_ds {
struct ipc_perm sem_perm; /* see Section 15.6.2 */
unsigned short sem_nsems; /* # of semaphores in set */
time_t sem_otime; /* last-semop() time */
time_t sem_ctime; /* last-change time */
.
.
.
};
#include <sys/sem.h> int semget(key_t key, int nsems, int flag);
|
Returns: semaphore ID if OK, 1 on error |
#include <sys/sem.h> int semctl(int semid, int semnum, int cmd, ... /* union semun arg */);
|
Returns: (see following) |
#include <sys/sem.h> int semop(int semid, struct sembuf semoparray[], size_t nops);
|
Returns: 0 if OK, 1 on error |
8.共享存储
struct shmid_ds {
struct ipc_perm shm_perm; /* see Section 15.6.2 */
size_t shm_segsz; /* size of segment in bytes */
pid_t shm_lpid; /* pid of last shmop() */
pid_t shm_cpid; /* pid of creator */
shmatt_t shm_nattch; /* number of current attaches */
time_t shm_atime; /* last-attach time */
time_t shm_dtime; /* last-detach time */
time_t shm_ctime; /* last-change time */
.
.
.
};
#include <sys/shm.h> int shmget(key_t key, size_t size, int flag);
|
Returns: shared memory ID if OK, 1 on error |
#include <sys/shm.h> int shmctl(int shmid, int cmd, struct shmid_ds *buf);
|
Returns: 0 if OK, 1 on error |
#include <sys/shm.h> void *shmat(int shmid, const void *addr, int flag);
|
Returns: pointer to shared memory segment if OK, 1 on error |
#include <sys/shm.h>
int shmdt(void *addr);
|
Returns: 0 if OK, 1 on error |
打印不同数据所存放的区域
#include "apue.h" #include <sys/shm.h> #define ARRAY_SIZE 40000 #define MALLOC_SIZE 100000 #define SHM_SIZE 100000 #define SHM_MODE 0600 /* user read/write */ char array[ARRAY_SIZE]; /* uninitialized data = bss */ int main(void) { int shmid; char *ptr, *shmptr; printf("array[] from %lx to %lx\n", (unsigned long)&array[0], (unsigned long)&array[ARRAY_SIZE]); printf("stack around %lx\n", (unsigned long)&shmid); if ((ptr = malloc(MALLOC_SIZE)) == NULL) err_sys("malloc error"); printf("malloced from %lx to %lx\n", (unsigned long)ptr, (unsigned long)ptr+MALLOC_SIZE); if ((shmid = shmget(IPC_PRIVATE, SHM_SIZE, SHM_MODE)) < 0) err_sys("shmget error"); if ((shmptr = shmat(shmid, 0, 0)) == (void *)-1) err_sys("shmat error"); printf("shared memory attached from %lx to %lx\n", (unsigned long)shmptr, (unsigned long)shmptr+SHM_SIZE); if (shmctl(shmid, IPC_RMID, 0) < 0) err_sys("shmctl error"); exit(0); }
发表评论
-
UNIX网络编程(1)-简介
2011-10-06 17:31 8041.bzero函数 bzero 等同于memset(void ... -
UNIX编程(14)-高级IO
2011-08-03 21:36 14241.非阻塞IO 对于一个给定的描述符有两种方法对其指定非阻塞 ... -
UNIX编程(13)-守护进程
2011-08-02 21:59 9641.守护进程的编程规则 1)用umask将文件模式创建屏蔽字 ... -
UNIX编程(12)-线程控制
2011-07-27 15:26 9511.线程限制 某些系统有线程的限制,可以通过sysconf函 ... -
UNIX编程(11)-线程
2011-07-27 14:34 9841.线程标识 每个线程都有一个线程ID,线程ID只在它所属的 ... -
UNIX编程(10)-信号
2011-07-20 21:18 10381.signal函数 #include ... -
UNIX编程(9)-进程关系
2011-07-12 14:41 11591.终端登录 2.网络登录 3.进程组 ... -
UNIX编程(8)-进程控制
2011-07-09 11:37 12131.进程标识符 每个进程 ... -
UNIX编程(7)-进程环境
2011-07-01 15:07 9091.main 函数 c程序总是从main函数开始执行,当内核 ... -
UNIX编程(6)-系统数据文件和信息
2011-06-28 16:35 12041.口令文件 口令文件存储在/etc/passwd中,是一个A ... -
UNIX编程(5)-标准IO库
2011-06-27 16:55 9791.流的定向 freopen函数清 ... -
UNIX编程(4)-文件和目录
2011-06-23 16:56 12841.stat,fstat,lstat函数 #include & ... -
UNIX编程(3)-文件IO
2011-06-21 17:45 14681.open函数 #include <fcntl.h&g ... -
UNIX编程(2)-UNIX标准化
2011-06-15 11:41 7211.ISO c 2.IEEE POSIX 3.Single U ... -
UNIX编程(1)-基础知识
2011-06-15 10:54 8411.登陆名 登陆名放在/etc ...
相关推荐
UNIX网络编程----进程间通信----卷2【第二版】源码
在Unix操作系统中,进程间通信(Inter-Process Communication, IPC)是多个进程之间共享数据、交换信息的关键技术。本实验源码着重展示了无名管道(unnamed pipe)和IPC通信的C语言实现,这对于理解Unix系统编程和多...
笔记_UNIX环境网络编程卷二进程间通信_中文第二版
UNIX网络编程第二卷-进程间通信-源代码 不同平台可能会遇到一些小问题 毕竟这些源代码有些年头了 关于我在fedora 11环境下编译出现的问题及解决办法见: ...
本书详细介绍了UNIX系统中进程间通信(IPC)的各种形式,这些通信机制对于提高UNIX程序性能至关重要,同时是开发不同主机间网络应用程序的基础。 书中首先从Posix IPC和System V IPC的内部结构开始讨论。Posix IPC...
《Unix网络编程第二卷 - 进程间通信》是一本深入探讨Unix系统中进程间通信(Inter-Process Communication, IPC)的经典著作。该书详细阐述了在Unix环境中,不同进程如何有效地交换数据和协调工作,涵盖了多种IPC机制...
《UNIX网络编程-第2卷-进程间通讯》是一本深入探讨UNIX系统中进程间通信(Inter-Process Communication, IPC)的经典著作。该书详细阐述了如何在多进程环境中实现有效的数据交换,这对于理解操作系统原理、开发高效...
《UNIX网络编程 第2版 第2卷 进程间通信》是UNIX系统下进行网络编程不可或缺的经典著作,尤其在深入理解和实践进程间通信(IPC,Inter-Process Communication)方面提供了丰富的知识和技术指导。本书详细阐述了如何...
本书全面深入地讲述了各种进程间通信(IPC)形式,它们是几乎所有复杂精致的UNIX程序的性能之关键。从网络编程角度看,理解IPC也是理解如何开发不同主机间网络应用程序的必要条件。本书从对Posix IPC和System V IPC...
UNIX网络编程 卷2 进程间通信(第2版)
UNIX网络编程第二卷 进程间通信
《UNIX网络编程 第2卷 进程间通信》是一本深入探讨UNIX环境下进程间通信机制的权威技术书籍。该书共分为四部分,涵盖了从基础套接口编程到高级套接口编程的多个方面,旨在为读者提供全面的进程间通信知识和编程实践...
UNIX网络编程卷二进程间通信.pdf
UNIX网络编程_卷2_进程间通信第二版.pdf,绝对高清,绝对正版,不用积分下载
UNIX 网络编程 卷2 进程间通信 第2版
UNIX网络编程(第2版)第2卷-进程间通信 linux unix 网络编程必备书籍
《UNIX网络编程卷2:进程间通信》是网络编程领域中的经典著作,深入探讨了在UNIX操作系统环境下如何实现进程间的高效通信。这部分源代码包含了书中多个章节的关键示例,可以帮助读者更好地理解和应用书中的理论知识...
UNIX网络编程第2卷(第2版-中文-高清-进程间通信-带目录) Linux经典书之一,UNP第2卷,必看!
《Unix环境高级编程》与《Unix网络编程:进程间通信》是两本在计算机科学领域具有深远影响力的经典著作。它们涵盖了Unix系统的核心概念和技术,对于理解操作系统原理、进行系统级编程以及深入研究网络通信有着不可...
UNIX网络编程卷2:进程间通信(第2版).pdf