【问题标题】:not exactly fifo不完全是先进先出
【发布时间】:2009-10-01 08:16:01
【问题描述】:

我很头疼,但找不到解决方案。请考虑这种情况:

我有写入器想要将非阻塞“队列”写入本地网络上的另一台机器,并且有一个读取器将读取数据(如果没有写入器,则为阻塞模式)并执行一些工作 A,然后返回一个小时,然后获取下一个数据。

所以场景是这样的:

  • 作家写
  • 作家写
  • 作家写
  • 作家写
  • 作家写
  • 读者阅读并完成工作

    在阅读器忙碌的同时:

  • 作家写
  • 作家写
  • 作家写
  • 作家写
  • 作家写
  • 等等...

我认为我可以使用 tcp 守护进程作为读取器来执行此操作,但这意味着它会与 fork(s) 同时运行,并且我希望读取器一次处理一个,因为它会做 cpu 饥饿的工作.

我曾想过让 tcp 服务器获取请求,然后向 FIFO 发出信号,并让另一个守护程序从 FIFO 中读取,但它具有相同的限制。

我的意思是 FIFO 必须在写入器写入时读取,并且我希望写入器的写入速度比读取器快很多倍。

一个 db 解决方案可以,但是 a) 它不是很快,b) 读者没有锁定..我不想用 sleep(x) 来实现它,这似乎不是一个好的编程技术.

有什么解决办法吗?

【问题讨论】:

    标签: c linux unix queue fifo


    【解决方案1】:

    这听起来好像你有一个producer-consumer problem。查看 Wikipedia 文章中的各种实现,看看其中一个是否满足您的需求。

    【讨论】:

      【解决方案2】:

      多线程似乎是要遵循的路径。创建一个启动读取或写入部分的线程,并在另一个任务上使用另一个线程。如果您需要将数据从读取器传递到写入器,则需要在线程之间提供一些线程安全的通信。您也可以考虑使用多个线程进行编写,具体取决于应用程序的上下文。

      在 POSIX 系统上使用纯 C,pthreads 是要走的路。

      【讨论】:

      • 别以为我能做到。作者是 php+apache,所以没有线程……只是很多脚本使用同一个套接字并在那里写。
      【解决方案3】:

      一个选项是拥有一个服务器(写入器)和一个客户端节点。 这概述了一般方法:

      服务器生成作业并将它们推送到本地队列中:

      // server thread
      while(true)
      {
           job = generate();
           jobs_queue.push(job); // push job to a local queue on the server
      }
      

      当客户端连接到服务器时,服务器上的一个线程会读取队列中的所有内容并将其推送到客户端。当没有连接的客户端时,队列需要保留作业。可能与您的情况无关。

      // server acceptor
      while(true)
      {
           c = wait_for_connection();
           while(connected(c))
           {
                while(queue.size() >  0)
                    c.write(queue.pop()); // send a job to the client
      
                // block till queue is not empty. can be achieved with sleep or by using a mutex.
           }
      }
      

      客户端节点将位于 tcp 套接字上,读取作业并将它们放入本地队列(在客户端上)。 有一个客户端线程是这样工作的:

      // client thread that poll from server
      while(true)
      {
          job = readNextJob(); // tcp, blocks if there is nothing to read
          queue.push(job);
      }
      
      // client thread that spawn jobs from queue
      while(true)
      {
          job = queue.pop(); // blocks if queue empty
          job.execute();
          job.waitForCompletion();
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-11-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多