① 在linux程序中如何使用命名管道实现对文件的读写、求帮助
//创建server管道。
mkfifo(Server_FIFO_Name,0777);
//打开服务器端口,等待读取。此时如果客户端还未写入数据服务器端会被阻塞。
server_fifo_fd = open(Server_FIFO_Name , O_RDONLY);
if( -1 == server_fifo_fd ){
fprintf( stderr , "Server fifo failure\n" );
exit(EXIT_FAILURE);
}
//从管道中读取数据。
read_res = read ( server_fifo_fd , &my_data , sizeof(my_data));
if(read_res > 0){
//将字符串翻转.
reverse ( my_data.str );
//将客户端的pid号加入回送管道文件名中.
sprintf ( client_fifo, Client_FIFO_Name , my_data.client_pid);
//打开回送管道。
client_fifo_fd = open ( client_fifo , O_WRONLY );
if( -1 != client_fifo_fd ){
//向管道中写入返回的数据.
write ( client_fifo_fd , &my_data, sizeof(my_data));
close ( client_fifo_fd );
}
}
② linux 管道原理
Linux原理的学习,我打算由浅入深,从上之下,也就是先了解个大概再逐个深入。先了解一下Linux的进程先。
一、Linux进程上下文
Linux进程上下文,我理解就是进程组成元素的集合。包括进程描述符tast_struct,正文段,数据段,栈,寄存器内容,页表等。
1)tast_struct
它是一种数据结构,存储着进程的描述信息,例如pid,uid,状态,信号项,打开文件表等。是进程管理和调度的重要依据。
2)用户栈和核心栈
顾名思义,用户栈是进程运行在用户态使用的栈,含有用户态执行时候函数调用的参数,局部变量等;核心栈是该进程运行在核心态下用的栈,保存调用系统函数所用的参数和调用序列。这两个栈的指针都保存在tast_struct结构中。
3)寄存器
保存程序计数器,状态字,通用寄存器,栈指针。
4)页表
线性地址到物理地址的映射
5)正文段,数据段。
二、Linux进程的状态
Linux中进程共有5个状态:就绪,可中断睡眠,不可中断睡眠,暂停,僵死。也就是说,linux不区分就绪和运行,它们统一叫做就绪态。进程所处的状态记录在tast_struct中。
三、进程的控制
1)进程树的形成
计算机启动后,BIOS从磁盘引导扇区加载系统引导程序,它将Linux系统装入内存,并跳到内核处执行,Linux内核就执行初始化工作:初始化硬件、初始化内部数据结构、建立进程0。进程0创建进程1,进程1是以后所有创建的进程的祖先,它负责初始化所有的用户进程。进程1创建shell进程,shell进程显示提示符,等待命令的输入。
2)进程的创建
任何一个用户进程的创建都是由现有的一个进程完成的,进程的创建要经过fork和exec两个过程。Fork是为新进程分配相应的数据结构,并将父进程的相应上下文信息复制过来。Exec是将可执行文件的正文和数据转入内存覆盖它原来的(从父进程复制过来的),并开始执行正文段。
3)进程的终止
系统调用exit()就可自我终结,exit释放除了tast_struct以外的所有上下文,父进程收到子进程终结的消息后,释放子进程的tast_struct。
4)进程的调度
进程的调度是由schele()完成的,一种情况是,当处理机从核心态向用户态转换之前,它会检查调度标志是否为1,如果是1,则运行schele(),执行进程的调度。另一种情况是进程自动放弃处理机,时候进行进程调度。
进程的调度过程分为两步,首先利用相关策略选择要执行的进程,然后进行上下文的切换。
四、进程的通信
进程的通信策略主要有,消息,管道,消息队列,共享存储区和信号量。
1)信息
消息机制主要是用来传递进程间的软中断信号,通知对方发生了异步事件。发送进程将信号(约定好的符号)发送到目标进程的tast_struct中的信号项,接收进程看到有消息后就调用相应的处理程序,注意,处理程序必须到进程执行时候才能执行,不能立即响应。
2)管道
我理解就是两个进程使用告诉缓冲区中的一个队列(每两个进程一个),发送进程将数据发送到管道入口,接收进程从管道出口读数据。
3) 消息队列
消息队列是操作系统维护的一个个消息链表,发送进程根据消息标识符将消息添加到制定队列中,接收进程从中读取消息。
4)共享存储区
在内存中开辟一个区域,是个进程共享的,也就是说进程可以把它附加到自己的地址空间中,对此区域中的数据进行操作。
5)信号量
控制进程的同步。
③ linux如何用管道实现显示文件内容,然后在文件最后显示行数等信息
cat 文件名称 | wc -l
④ linux管道实现sftp自动登陆
lftp -u user,pass sftp://x.x.x.x
⑤ Linux C 通过管道实现文件复制
#include"stdio.h"
#include"stdlib.h"
#include"unistd.h"
#include"sys/types.h"
#include"sys/stat.h"
#include"string.h"
#include"fcntl.h"
#include"errno.h"
#define FIFO1 "/tmp/fifo"
#define MAXLINE 100
void client1(int);
void client2(int);
int main(int argc,char **argv)
{
int writefd;
writefd=open(FIFO1,O_WRONLY,0);
client1(writefd);
client2(writefd);
close(writefd);
unlink(FIFO1);
exit(0);
}
void client1(int writefd1)//实现从文件写到管道,自己创建一个aa.txt文件
{
char buff[MAXLINE];
int fd;
memset(buff,0,sizeof(buff));
fd=open("aa.txt",O_CREAT|O_RDWR,S_IRWXU);
read(fd,buff,sizeof(buff));
write(writefd1,buff,sizeof(buff));
close(fd);
}
void client2(int writefd2)//)//实现从管道写到另一个文件
{
char buff[MAXLINE];
int fd;
fd=open("bb.txt",O_CREAT|O_RDWR,S_IRWXU);
read(writefd2,buff,sizeof(buff));
write(fd,buff,sizeof(buff));
close(fd);
}
我这里省略了许多判断,自己加哈
如有问题,在线交流
⑥ linux 管道和输入输出重定向如何用c语言结合实现
两种方法(实用)
1:直接系统调用,管道建立分命名管道和非命名管道,使用参考unix手册或UNP第二卷进程间通信。输入输出重定向就用read(source);write(destination);
2:使用系统shell
功能:即调用
system("cat
file.a
|
grep
bb
>
file.c");
⑦ Linux下利用匿名管道实现父子进程通信,要求从父进程输入整数 n 到子进程,算出1到n的偶数和
#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>
intmain()
{
intfd[2];
//创建二个fd,fd[0]管道用于读,fd[1]管道用于写
pipe(fd);
//创建进程
pid_tpid=fork();
if(pid==0)
{
//子进程,读取整数n
intn;
read(fd[0],&n,sizeof(int));
//计算1-n的偶数和
intsum=0;
for(inti=1;i<=n;++i)
{
if(i%2==0)
{
sum+=i;
}
}
printf("Thesumofallevennumberfrom1to%dis%d ",n,sum);
//子进程工作完后使用exit(0)退出
exit(0);
}
else
{
//父进程,写入整数n
intn;
printf("Pleaseinputn:");
scanf("%d",&n);
write(fd[1],&n,sizeof(int));
}
}
Linux 环境下编译及测试结果如下:
⑧ 在linux下可以用命名管道实现c程序与qt的数据通信吗
当然可以了。不过可以直接使用dbus进行进程间通讯,C程序发送数据(libdbus),Qt去捕获信号(QDbus),这样来的更方便点,否则你要自己封装管道的收发接口。
⑨ Linux管道实验题
<pre t="code" l="cpp">#include <unistd.h>
#include <stdio.h>
//警告: 该程序未做错误验证, 未关闭管道(由系统自动关闭)
int main()
{
int p2c[2]; // 该管道父进程写,子进程读
int c2p[2]; // 该管道子进程写,父进程读
// 创建2条管道
pipe(p2c);
pipe(c2p);
int pid = fork();
int fd_read, fd_write; // 这两个描述符用于保存某进程读端和写端
int pid_my; // 保存某进程自身的pid
int pid_other; // 另一进程的pid,通过
if ( pid == 0 ) { // 子进程
fd_read = p2c[0];
fd_write= c2p[1];
// 通过getpid取得自身pid,写到管道里
pid_my = getpid();
write(fd_write, pid_my, sizeof(int));
// 从另一管道读取另一进程的pid
read(fd_read, pid_other, sizeof(int));
// 打印读取到的pid
printf("Recive pid : %d\n", pid_other);
} else { // p
fd_read = c2p[0];
fd_write= p2c[1];
pid_my = getpid();
// 由于子进程是先写自身pid,父进程最好先读取子进程的pid
read(fd_read, pid_other, sizeof(int));
write(fd_write, pid_my, sizeof(int));
printf("Recive pid : %d\n", pid_other);
}
return 0;
}
⑩ Linux线程间可否用管道通讯,如何实现
线程间通信有很多种。如果仅仅使用共享的变量来交换数据,那么不需要通过内核。 但是,共享变量为了保证同步,通常会进行互斥操作,这个是需要通过内核的。