boost中线程和function的疑问

yangyunzhao 2012-06-05 11:42:56
问题请见代码中的注释

#include "stdafx.h"
#include <boost//thread.hpp>
#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <iostream>

using namespace std;

void fun1()
{
while(1)
{
cout << "fun1" << endl;
boost::this_thread::sleep(boost::posix_time::millisec(50));
}
}

void fun2(long l1, long l2)
{
while(1)
{
cout << "l1=" << l1 << " l2=" << l2 << endl;
boost::this_thread::sleep(boost::posix_time::seconds(1));
}
}

long fun3(long l1, long l2, long l3)
{
while(1)
{
cout << "l1=" << l1 << " l2=" << l2 << " l3=" << l3 << endl;
boost::this_thread::sleep(boost::posix_time::seconds(1));
}
}

long fun4(long l1, long l2, long l3, long l4)
{
while(1)
{
cout << "l1=" << l1 << " l2=" << l2 << " l3=" << l3 << " l4=" << l4 << endl;
boost::this_thread::sleep(boost::posix_time::seconds(1));
}
}

int main(int argc, char* argv[])
{
boost::thread tr1(fun1);
boost::thread tr2(fun2, 1, 2);
boost::thread tr3(boost::bind(fun3, 1, 2, 3));

boost::function< void(void)> func4 = boost::bind(fun4, 1, 2, 3, 4);
/* 1、为何这里写boost::function< long(long, long, long, long)> func4 = boost::bind(fun4, 1, 2, 3, 4);的时候
* 下面的boost::thread tr4(func4);就无法通过编译?注:我用的VS2008
* 2、上述两种写法有何区别?为何可以写参数模块可以写 void(void) 呢?
*/

boost::thread tr4(func4);

tr1.join();
tr2.join();
tr3.join();
tr4.join();
return 0;
}

...全文
97 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
yangyunzhao 2012-06-06
  • 打赏
  • 举报
回复
真心求助
yangyunzhao 2012-06-06
  • 打赏
  • 举报
回复
不太理解您的回复,不好意思
yangyunzhao 2012-06-06
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 的回复:]
bind实现partial function application,通过现有的函数绑定参数制造新的call wrapper,结果对应的签名必然和原来的不同。long(long, long, long, long)被绑定4个参数以后就只剩long(void)了,当然,可以转为void(void)。
线程入口要参数……用支持variadic template实现的C++11的std::thread……
[/Quote]
非常感谢您的回复!
FrankHB1989 2012-06-06
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 的回复:]

bind实现partial function application,通过现有的函数绑定参数制造新的call wrapper,结果对应的签名必然和原来的不同。long(long, long, long, long)被绑定4个参数以后就只剩long(void)了,当然,可以转为void(void)。
线程入口要参数……用支持variadic template实现的C++11的std::threa……
[/Quote]
签名→类型。
匿名实体无所谓签名。
  • 打赏
  • 举报
回复
lz先去看看bind的用法
FrankHB1989 2012-06-06
  • 打赏
  • 举报
回复
bind实现partial function application,通过现有的函数绑定参数制造新的call wrapper,结果对应的签名必然和原来的不同。long(long, long, long, long)被绑定4个参数以后就只剩long(void)了,当然,可以转为void(void)。
线程入口要参数……用支持variadic template实现的C++11的std::thread吧(也有std::bind/std::function可以用)。

zhangsongcui 2012-06-06
  • 打赏
  • 举报
回复
fun4总共4个参数,在你全绑定在func4中了,那么再调用func4时就不用参数了
func4()就相当于fun4(1,2,3,4)

boost::thread的线程入口是不能有参数的
基于事件驱动的网络框架源码 首先看一下Server类,这个类就是整个框架的核心类,在这个类只需要 s=new Server(8883,4); s->setUserConnectionCallback(onConnect); s->setUserMessageCallBack(onMessage); s->start(); 就可以启动一个4个线程在8883端口监听的完整的网络程序,其的两个onXXX就是网络程序需要处理的业务 Server类包括了有一个重要的类叫做Eventlooper这个类就是对epoll的封装,要用epoll_ctl注册到epoll上的fd又被封装为Channel类,当有数据到来需要操作时,channel的几个函数指针就指向了需要回调的函数, 这里使用了boost库的function的函数定义为: typedef boost::function EventCallBack; 在epoll返回的时候Eventlooper会遍历可以操作的所有channel,并调用其成员函数handleEvent,该函数会判断events,也就是EPOLLIN EPOLLPRI等,并更具相应的需要去调用处理函数。 这里的Channel并不直接使用而是做基类存在的,更直接的操作在Acceptor和TcpConnection,其的 Acceptor 对应了接受连接的socketfd,而TcpConnection则封装了socket的读写操作,在Server的构造函数会创建一个Acceptor类,真正accept成功以后又会调用到Server的OnConnection函数,这个函数会根据每个线程的负载将客服端连接的fd注册进相应线程的epoll(当然在单线程的情况下就只有一个epoll)。最后一个作为缓冲区的类charbuff,用链表将单个7KB的缓冲区穿在一起,当数据大于7kb的时候会自动将其释放,避免内存不足,如果数据的块数多余一块那么发送数据就会调用writev。至此整个框架的流程就都已经清楚了,一个简单的实现。 在此还要感谢一下linux多线程网络服务器编程的作者陈硕,CINF的实现部分就是参考其网络框架muduo来的。

64,648

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧