繁体   English   中英

简单的Linux IPC问题

[英]Simple Linux IPC Question

目前我有一个客户端进程和一个服务器进程。 客户端进程需要经常联系服务器进程以交换数据,但需要知道服务器的pid才能这样做。 客户应该如何知道如何做到这一点? 我想避免重复的硬盘访问。 此应用程序仅在linux下运行。 目前,服务器使用其生存的pid或RAM磁盘设置锁定文件。 客户端检查文件。 如何有效地完成此交易,以便服务器可以向客户端发送信号? (注意:客户端是PHP,服务器是c)

一些想法:

  1. 没做什么; 如果您反复阅读它,读取光盘文件(在适当的永久光盘上)将不会导致任何IO,因为该文件已经在缓存中。
  2. 重构您的系统,这样您就不需要知道pid文件
  3. 你确定你真的在乎吗? 过早优化和所有这些。 你这样做每秒多少次,1000或更多?

我假设,当你说“过程”时,这两个是在同一台机器上? 如果是这样,您可以在/tmp目录中使用命名FIFO。 这是使用IPC和带有fork()的名为FIFO /tmp/test.fifo的两个进程的示例:

#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;
}

因此,只要两个进程都知道FIFO的完整路径,它们就可以读取和写入它。

通常你不使用pid,而是使用某种地址 - 一个IP地址(包括端口),一个Unix域套接字地址,一个文件系统中的路径,或者建立在其中一个之上的一些更高级别的IPC系统( D-Bus,X等)到达服务器并与之通信。 pid唯一有用的是发送信号,这可能是一种非常糟糕的通信方式,如果将客户端和服务器分离为单独的权限域,则无法工作。

其他一些选择包括:

  1. 设置服务器以侦听特定端口。
  2. 服务器可以设置命名管道,客户端可以通过它与之通信。

我认为你可以在non_blocking模式下使用名称IPC消息队列。 我不知道命名管道是否支持non_blocking模式,但如果是,那么你也可以使用它。 在non_block模式下,您只需注册队列描述符即可发出信号并进入常规等待状态。 如果队列中有任何活动,您的进程将会清醒。 请通过互联网进行一些搜索,你可以找到许多相同的例子。

为了给出正确/准确的答案,我应该知道您的服务器进程的设计。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM