- 论坛徽章:
- 0
|
/**********************************************************************************
* 说进程通讯之前先解释什么是进程?
*
* ===================
* ┏━━━━━━━┓
* ┃ A B C ┃
* ┃ │ ┃ │ ┃
* ┃ │ ┃ │ ┃
* ┃ │ ┃ │ ┃
* ┃ │ ┃ │ ┃
* ┃ │ ▉ │ ┃
* ┃ │ ┃ │ ┃
* ┃ │ ┃ │ ┃
* ┃ ▉ ┃ │ ┃
* ┃ │ ┃ │ ┃
* ┃ │ ┃ │ ┃
* ┃ │ ┃ │ ┃ 细竖线表示线程;
* ┃ │ ┃ ▉ ┃ 粗竖线表示主进程;
* ┃ │ ┃ │ ┃ 方块表示当前位置;
* ┃ │ ┃ │ ┃ 方框表示进程封装;
* ┃ 1 2 3 ┃ 字母表示进程名称;
* ┃ └─╂─┘ ┃ 数字表示进程CPU地址。
* ┗━━━━━━━┛
* 我就是进程
*
*
* 1.进程如树根,线程如树干,所有线程都直接或间接由进程得来。
* 2.B线程是程序运行时创建的,由他创建A和C,它就是树子的主树
* 干,其它小树干(树枝)由它长出
* 3.每个树枝(线程)几乎可以做到互不影响,砍断一个另两个仍然生长
* 4.CPU如生长素,按顺序分别在ABC三个地方施加向上的一个推动线程
* 的力,虽然CPU在某个时刻只在一个地点出现,但由于快速的切换导
* 致我们无法发现,犹如快速切换具有相似性的一组静态图片可以使
* 我们看到运动图像一样。
* 5.当所有的树干都被砍断,树根的存在就不再有意义了,所以它会自
* 动地“烂掉”。
* from CSDN Google :) 解释的不是很准确但是很生动 简单的说是OS分配运行空间的基本单位
* 注意 有MMU 和无MMU 都有进程这个概念 实现的方式是不同 但是必须要有用户代码参与实现
* 这里的指的的core 代码 可以几句汇编指令 也可以比较复杂 比如linux kernel
* 管道用于通讯的一种机制 上世纪60年代提出 一直用到今天
* 匿名管道 进程之间要有亲戚关系才可以使用 还会有一种叫 有名管道突破这个限制
*
*/
大家先看这里 我对这片文章补充了下面内容
在linux 进程通讯方式简写为IPC 进程之间无法看见对方必须采用特殊方式管道是其中一种 本文介绍 匿名 和FIFO 2种
匿名管道必须是 亲缘关系的进程 半双工方式
看程序
/* gcc xx.c*/
/* 运行参数 ./a.out xxxxxxxxxxxxxxxxxx */
#include
#include
#include
#include
#include
static struct{
int pipe_fd[2];
pid_t pid;
char r_buf[1];
} data_pcb={0,};
#define init_pipe(object,member) \
do{\
if (pipe(object.member)) perror("pipe create error"); \
}while(0)
#define Create_child(object,member) \
do{\
object.pid=fork();\
}while(0)
extern int
main(int argc,char * argv[]){
init_pipe(data_pcb,pipe_fd);
if(argc Create_child(data_pcb,pid);
if(!data_pcb.pid){
close(data_pcb.pipe_fd[1]); //close write
while(read(data_pcb.pipe_fd[0],&(data_pcb.r_buf),1)>0) //read is block!
write(1,&(data_pcb.r_buf),1);
write(1,"\n",1);
close(data_pcb.pipe_fd[0]);
_exit(0);
}
if(data_pcb.pidwrite(data_pcb.pipe_fd[1],argv[1],strlen(argv[1])); //write is block!
close(data_pcb.pipe_fd[1]);
wait(NULL);
puts("Game Over!\n");
return 0;
}
//=============================================================================
但是我们能 突破这个限制 通过 dup 传递重定向 fd 看下面这个程序如何做到
#include
#include
#include
#include
int main()
{
int data_processed;
int file_pipes[2];
const char some_data[] = "123";
pid_t fork_result;
if (pipe(file_pipes) == 0) {
fork_result = fork();
if (fork_result == (pid_t)-1) {
fprintf(stderr, "Fork failure");
exit(EXIT_FAILURE);
}
if (fork_result == (pid_t)0) {
close(0); int x=dup(file_pipes[0]); close(file_pipes[0]); close(file_pipes[1]); execlp("od", "od", "-c", (char *)0);
exit(EXIT_FAILURE);
}
else {
close(file_pipes[0]);
data_processed = write(file_pipes[1], some_data, \
strlen(some_data));
close(file_pipes[1]);
printf("%d - wrote %d bytes\n", (int)getpid(), data_processed);
}
}
exit(EXIT_SUCCESS);
}
gcc xxx.c
./a.out
RUN
@@@@@debian-NjingLt:~/C/Clib/process$ 0000000 1 2 3
0000003
//==============================================================================
命名管道
我们先熟悉一个 命令 mknod 通过man mknod 参看用法 POSIX 还为我们提供一个mkfifo函数方便C编程
我们就在shell下学习 namepipe 如下
@debian-NanJing:~/C/Clib/process$ file xxxxxxxx: fifo (named pipe)@debian-NanJing:~/C/Clib/process$ ls -lh xxxxprw-r--r-- 1 vivi vivi 0 13:43 xxxx@debian-NanJing:~/C/Clib/process$ @debian-NanJing:~/C/Clib/process$ cat ^C@debian-NanJing:~/C/Clib/process$ cat [1] 11431@debian-NanJing:~/C/Clib/process$ echo "Namepipe? >xxxx Namepipe[1]+ Done cat @debian-NanJing:~/C/Clib/process$
我们通过命名管道把进程链接起来 按照通讯理论可以连接成星型 和菊花链 APUE2 上有图大家自己去看 重点看 man 7 pipe
PIPE_BUF
POSIX.1-2001 says that write(2)s of less than PIPE_BUF bytes must be atomic: the output data is written to the
pipe as a contiguous sequence. Writes of more than PIPE_BUF bytes may be non-atomic: the kernel may interleave
the data with data written by other processes. POSIX.1-2001 requires PIPE_BUF to be at least 512 bytes. (On
Linux, PIPE_BUF is 4096 bytes.) The precise semantics depend on whether the file descriptor is non-blocking
(O_NONBLOCK), whether there are multiple writers to the pipe, and on n, the number of bytes to be written:
O_NONBLOCK disabled, n PIPE_BUF
The write is non-atomic: the data given to write(2) may be interleaved with write(2)s by other process; the
write(2) blocks until n bytes have been written.
O_NONBLOCK enabled, n > PIPE_BUF
If the pipe is full, then write(2) fails, with errno set to EAGAIN. Otherwise, from 1 to n bytes may be
written (i.e., a "partial write" may occur; the caller should check the return value from write(2) to see
how many bytes were actually written), and these bytes may be interleaved with writes by other processes.
PIPE_BUF 在头文件 #include
下面 3个 demo 是 namepipe 的具体的操作 有兴趣可以下载调试下 3个demo 都写了简单的Makefile文件 SUN x4100 和 debian-lenny 测试过
make run 就可以演示
重定向
demo1
demo2
demo3
本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u3/94090/showart_2111629.html |
|