【问题标题】:C++ Program Flow: Sockets in an Object and the Main FunctionC++ 程序流程:对象中的套接字和主函数
【发布时间】:2010-06-09 04:09:05
【问题描述】:

关于使用套接字的 C++ 程序流,我有一个相当棘手的问题。

基本上我所拥有的是:一个简单的命令行套接字服务器程序,它侦听套接字并一次接受一个连接。当该连接丢失时,它会打开以供进一步连接。

该套接字通信系统包含在一个类中。该类完全能够接收连接并将接收到的数据镜像到客户端。但是,该类使用非面向对象的 UNIX 套接字。

我的问题是在我的 main() 函数中,我有一行 - 创建该对象实例的那一行。然后对象初始化并等待。但是一旦获得连接,对象的初始化函数就会返回,当这种情况发生时,程序就会退出。在程序退出之前,我如何以某种方式等到该对象被删除?

总结:

  1. main() 创建对象实例
  2. 对象监听
  3. 收到连接
  4. 对象的初始化函数返回
  5. main() 退出 (!)

我想要的是 main() 在退出之前以某种方式延迟,直到该对象完成它正在做的事情(也就是它会删除自己)。

有什么想法吗?

【问题讨论】:

  • 如果你的主要功能什么都不做,这个对象应该如何运行它的功能?
  • 它使用线程吗?你能发布一下 API 的工作原理吗?
  • 不,没有线程。我想我会使用阻塞函数(下面是 Jeremy Friesner 在 cmets 中的答案),但我不确定如何在不吃 CPU 的情况下让它阻塞。

标签: c++ sockets program-flow


【解决方案1】:

如果您发布一些代码会更容易自信地回答,但它似乎很简单......在 main() 的内容周围添加一个 while(1) 循环:

int main(int, char **)
{
   while(1)
   {
      [...]
   }
}

【讨论】:

  • 问题是,那会继续创建多个对象。 main() 中的行是这样的:NetworkLink *networkLink = new NetworkLink(new UNIXSocketServerCommProtocol()); 不幸的是我不能在这里发布任何额外的代码;目前是保密的。但是,我可以说 comm 类工作正常。只是程序还没来得及工作就退出了。
  • 另外,我还可以补充一点,在对象创建之后添加一个 while(1) 循环也不是一个选项;我们的要求之一是效率(该程序最终将嵌入远程机器人系统中),因此电池寿命至关重要。如果它占用过多的处理器周期,它将无法工作。
  • 您需要在循环迭代结束时调用 networkLink->waitForSessionToEnd() 。该调用应该阻塞,直到 TCP 连接断开。 (如果对象没有这样的调用,那么您需要添加一个。正如后续答案所示,pthread_join() 可能是该方法实现的一部分)
  • 有道理;我只是不明白它会如何在不使用 CPU 的情况下阻塞。我知道你可以有一个布尔变量,然后执行 while(!var),但这又是 CPU 密集型的。我问过很多人如何进行非 CPU 密集型阻塞调用,但从来没有得到一个有效的好答案——也许你可以提出一些建议?
  • 另外,网络类本身不使用线程,如果这有影响的话。
【解决方案2】:

有几种可能的解决方案,但如果没有更多信息,很难确定哪一个最适合您的情况。

我的第一个想法是将通信部分放在不同的线程中。这使得编程稍微复杂一些,但是当连接关闭时,只有线程终止。

第二个想法是 Jeremy Friesner 的想法与 while 循环的变体。您似乎因为效率而反对它。我的建议:先建立一些有效的东西,然后再处理效率。为了节省资源,请在构造函数之后调用 sleep()。

【讨论】:

    【解决方案3】:

    我想要的是 main() 在退出之前以某种方式延迟,直到该对象完成它正在做的事情(也就是它会删除自己)。

    这听起来像是对象正在启动一个线程。

    假设是这种情况,您有几个选择:

    1. 调用pthread_join等待对象启动的线程完成。
    2. 有主呼叫pthread_exit。这只会结束线程而不是整个进程。

    【讨论】:

      【解决方案4】:

      如果对象正在启动一个线程,也许 API 中有某种 .wait() 方法,或者您可以访问内部线程对象并进行 join()?

      如果没有并且您无法更改 API,那么您将不得不在里面有一段时间 (1) 和睡眠......并且可能看起来不太好。

      您的 Network 类似乎在您不知道或没有能力等待它的情况下启动了一个线程。如果 Network 类确实可以满足您的所有需求,那么在其中使用线程有什么意义,因为您同时只有一个客户端?

      【讨论】:

        【解决方案5】:

        通常,服务器有一个监听套接字,您循环接受客户端连接,为每个在单独线程中执行的连接创建一个新的连接处理类。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-05-18
          • 1970-01-01
          • 2017-10-13
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多