简单的Linux IPC问题
目前我有一个客户端进程和一个服务器进程。客户机进程需要经常联系服务器进程以交换数据,但需要知道服务器的pid才能这样做。客户应该如何知道如何做到这一点?我想避免重复访问硬盘。此应用程序仅在linux下运行。目前,服务器设置了一个带有pid的锁文件,该pid是有效的,或者是一个RAM磁盘。客户端检查文件。我如何才能高效地完成此事务,以便服务器可以向客户端发送信号?(注意:客户端是PHP,服务器是c)其他一些选项包括:简单的Linux IPC问题,c,linux,ipc,C,Linux,Ipc,目前我有一个客户端进程和一个服务器进程。客户机进程需要经常联系服务器进程以交换数据,但需要知道服务器的pid才能这样做。客户应该如何知道如何做到这一点?我想避免重复访问硬盘。此应用程序仅在linux下运行。目前,服务器设置了一个带有pid的锁文件,该pid是有效的,或者是一个RAM磁盘。客户端检查文件。我如何才能高效地完成此事务,以便服务器可以向客户端发送信号?(注意:客户端是PHP,服务器是c)其他一些选项包括: 将服务器设置为侦听特定端口 服务器可以设置一个命名管道,客户端可以通过该管道与之
- Unix域套接字
- 我想,当你说“过程”时,这两个在同一台机器上?如果是这样,您可以在
/tmp
目录中使用命名的FIFO。这是一个使用IPC的两个进程的示例,命名为FIFO/tmp/test.FIFO
和fork()
:
#包括
#包括
#包括
#包括
#包括
#包括
#包括
int errno;
int main(int argc,字符**argv)
{
字符fifo_路径[]=“/tmp/test.fifo”;
字符缓冲区[128];
int result=mkfifo(fifo_路径,0600);
printf(“mkfifo结果=%d\n”,结果);
if(errno==EEXIST)
printf(“errno==EEXIST\n”);
pid_t child=fork();
如果(子项==0)
{
printf(“%d>子级;打开fifo\%s\”进行写入\n“,getpid(),
先进先出路径);
文件*fifo=fopen(fifo_路径,“w”);
缓冲区中的字符[128];
fgets(在缓冲区中,128,标准输入);
FPUT(在缓冲区中,fifo);
fclose(先进先出);
}
其他的
{
printf(“%d>父级;打开fifo\%s\”进行读取\n“,getpid(),
先进先出路径);
文件*fifo=fopen(fifo_路径,“r”);
FGET(缓冲器、128、fifo);
if(缓冲区[0]==EOF)
printf(“%d>获得EOF\n”,getpid());
其他的
{
缓冲区[strlen(buffer)-1]=0;
printf(“%d>读取字符串\%s\”\n),getpid(),buffer);
}
fclose(先进先出);
}
返回0;
}
因此,只要两个进程都知道FIFO的完整路径,它们就可以对其进行读取和写入。通常您不使用pid,而是使用某种类型的地址—IP地址(包括端口)、Unix域套接字地址、文件系统中的路径,或者在其中一个(D-Bus、X等)之上构建的某个更高级别的IPC系统到达服务器并与服务器通信。pid唯一有用的是发送一个信号,这可能是一种非常糟糕的通信方式,如果您将客户端和服务器分离到单独的特权域中,它将不起作用。我认为您可以在非阻塞模式下使用名称IPC消息队列。我不知道命名管道是否支持非阻塞模式,但如果是,您也可以使用它。在非块模式下,您只需注册队列描述符来发送信号,然后进入常规等待。如果队列上有任何活动,您的进程将被唤醒。请在互联网上做一些搜索,你可以找到许多这样做的例子
要给出正确/准确的答案,我应该了解您的服务器进程设计。这是我已经做过的,但问题是同步。目前,我的设置是让客户端向服务器发送信号,表明它已准备好进行事务,然后事务在服务器中的信号处理程序函数中发生。它如何知道向哪个pid发送信号?您不需要知道pid;您只需要知道客户机是否正在读取FIFO。有一种方法可以做到这一点;不过我不确定。我相信服务器在写入FIFO时会阻塞,直到它被打开读取。您可以使用某些参数创建FIFO,这意味着服务器不会阻塞,但如果没有读取FIFO,服务器将接收SIGPPIPE信号。我希望这有帮助。所以。。。没有人回答我的问题。我的问题不完全是关于IPC的。它是关于IPC的同步。我已经让客户端和服务器通过命名管道进行通信。问题是服务器应该如何知道何时监听管道。现在,这是通过信号实现的(因此,需要知道服务器的pid并将其保存在重复访问信息不会导致垃圾邮件磁盘读取的地方)。你是说,服务器应该在不做任何其他事情的情况下,在管道上监听客户端的通信,而不是尝试同步吗?好的,好的,我喜欢这样的声音,我已经做了一些不愉快的事情来纠正privs,但是如果我实现了这一点,我的服务器如何知道客户机何时请求了什么?它大部分时间都需要做一件事(为客户机收集数据),然后当客户机要求它传输数据时。现在,一个信号处理程序允许我在收到信号时异步执行代码。但是有一个插座。。。我可以为套接字设置某种类型的事件处理程序吗?我应该分叉并让一个分支只循环监听套接字吗?有两种通用方法。一种是使用
select
(或poll
)将服务器构造为一个事件循环,以等待来自多个文件描述符中任何一个的输入,还可能等待从缓冲区写入输出的能力。另一种是在IO中使用线程或单独的进程。但是,如果您使用流程,您将遇到一个问题,即如何使流程与用户进行通信
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <linux/stat.h>
int errno;
int main(int argc, char** argv)
{
char fifo_path[] = "/tmp/test.fifo";
char buffer[128];
int result = mkfifo(fifo_path, 0600);
printf("mkfifo result = %d\n", result);
if (errno == EEXIST)
printf("errno == EEXIST\n");
pid_t child = fork();
if (child == 0)
{
printf("%d> child; opening fifo \"%s\" for writing\n", getpid(),
fifo_path);
FILE* fifo = fopen(fifo_path, "w");
char in_buffer[128];
fgets(in_buffer, 128, stdin);
fputs(in_buffer, fifo);
fclose(fifo);
}
else
{
printf("%d> parent; opening fifo \"%s\" for reading\n", getpid(),
fifo_path);
FILE* fifo = fopen(fifo_path, "r");
fgets(buffer, 128, fifo);
if (buffer[0] == EOF)
printf("%d> got EOF\n", getpid());
else
{
buffer[strlen(buffer) - 1] = 0;
printf("%d> read string \"%s\"\n", getpid(), buffer);
}
fclose(fifo);
}
return 0;
}