使用IO_Service已经创建的线程更有效率

时间:2013-04-15 23:08:10

标签: c++ multithreading boost-asio

在下面的示例中,我使用的是boost ASIO,这里有一个线程就绪并且总是在等待作业。它将始终线性地执行作业(就像我理解的那样将作业存储在队列中)以下代码片段解释了我的观点。

void WorkerThread( boost::shared_ptr< boost::asio::io_service > io_service )
{
    io_service->run();
}

void PrintNum( int x )
{
  //Do somejon
}

boost::shared_ptr< boost::asio::io_service > io_service( new boost::asio::io_service);
boost::shared_ptr< boost::asio::io_service::work > work(new boost::asio::io_service::work( *io_service ));
boost::asio::io_service::strand strand( *io_service );
worker_threads.create_thread( boost::bind( &WorkerThread, io_service ) );
//Give the thread (which is already active) some work to do
for(int i=0;i<2;i++)
{
  strand.post( boost::bind( &PrintNum, i ) );
}

问题1

现在我的问题是上述方法是否比启动独立线程更快更有效(例如通过使用boost::thread)我知道在独立线程的情况下,例如boost::thread启动线程可能不是线性的(线程2可能在线程1之前运行)我的问题是,如果只涉及一个线程哪个机制会更快?有没有任何开销因为eof boost :: bind

问题2 在上面的示例中,启动了2个等待工作的线程(thread1和thread2)。现在我想知道当连续两次工作时究竟发生了什么

for(int i=0;i<2;i++)
{
  strand.post( boost::bind( &PrintNum, i ) );
}

每个线程获得一个作业,但线程2不会在线程1之前完成。我的问题是线程2发生了什么,而线程一是lauching,它甚至在线程一是lauching时输入PrintNum方法。在这种情况下,当涉及到性能时,有多个线程有什么意义?

1 个答案:

答案 0 :(得分:1)

线程和异步i / o不是性能优化。它们是用于隐藏延迟的技术。

问题1:boost :: bind相对便宜。它只是创建一个函数对象。启动线程非常昂贵。线程之间的同步有点昂贵(不像创建新线程那么昂贵,但比创建函数对象更昂贵)。像strand.post()这样的操作可能会进行大量的同步(在线程之间传递值,确保在特定的订单中发生事情)。

问题2:线程2(假设库创建它而不是以某种方式优化它)将阻止等待线程1完成其处理,然后线程2甚至调用PrintNum。

如果他们将大部分时间用于互相拦截,那么拥有两个主题毫无意义。

依赖操作的序列应该大部分映射到同一个线程。 (就像PrintNum(0); PrintNum(1)在你的情况下:你希望它们按顺序运行,所以把它们放在同一个线程中。)

如果你有事情要做,那么只开始一个新的线程几乎完全独立于你当前正在做的事情。例如:您正在编写一个与多个用户或设备建立连接的服务器。由于每个用户或设备都以自己的速度工作,请求服务或响应来自服务器的问题,因此您可能希望创建一个线程来与每个用户或设备进行交互。这样,如果一个用户离开几分钟,所有其他用户可以继续与他们的线程交互,而不会阻止等待离开的用户。但是您为单个用户执行的服务按照特定顺序进行(“用户要求A,所以我查找A,对其进行一些处理然后将其发送回用户”)所以不要将服务分开为一个用户执行不同的线程。