关于杂碎的一些c++多线程编程问题,由winapi到boost::thread

构思了下,觉得到时写的时候用上多线程什么的,肯定是不能避免的, 而c++实现多线程又是特别考验人的和折磨人的,所以就先开个小程序把有可能出现的问题都搞搞吧

 

第一个:超级烦的LPVOID的,其实我觉得这种明明方式还真的挺丑的,直译的话是“老婆空”么?哎…怪不得程序员都那么屌丝。好吧,其实是这样的,因为这个东西呢,是个可以指向任意类型的指针,好像是为了平台的可移植性而搞的吧,反正在winapi里面(当然也就包括了要用到的线程的接口和很有可能也要用到的winsock这些),这个东西是出现很多的,而可想而知我自己的里面,经常会有像char*啊string之类这些东西的出现,所以转换就成了一个问题。好吧,原来直接转的话还貌似不行,或者是极端的麻烦,网上很多方法,有些还涉及到了什么LPTSTR,LPCTSTR,LPWSTR,其实我真的觉得在这个方面c++易用性太低了,哎

 

说说我的需求下,我所采用的并且行之有效的办法吧:首先发现一般情况下char*还是很不错的,很通用,string毕竟不是标准库里面的东西,它只是个经过包装后的类

调用线程的api的时候,要传进字符串之类的东西,用char*吧,如果本来有些东西是string的话,string.c_str()是个非常棒的函数,返回值是char*,赋值给Cstring也可以,对了,cstring我现在是暂时用不到了,但是原来它要包含的头文件是<altstr.h>,额,真别扭,查了msdn才知道

char* test_cahr = "test_char";
HANDLE hThread = CreateThread(NULL, 0, Fun, (LPVOID*)test_char, 0, NULL);

DWORD WINAPI Fun(LPVOID IpParamater)
{
    char* try_char = (char*)IpParamater;
}

上面这样搞就可以了,无非就是char和lpvoid两个类型的指针的转换,比其他任何方法都简单明了多了。

 

好吧,这篇已经是半个多月之前写下来的笔记了,那时候貌似还没考试搞boost,现在上面的很丑的内带winapi实现我也已经彻底决定放弃它了,为什么呢?

因为boost有thread库…

boost现在在c++11里面已经有很大一部分原本的库的东西成为了标准了,貌似当然也包括这个线程库,也就意味着以后c++11流行了之后,没有人会再记得winapi这样这么土鳖的方式是怎么写的了,所以我就当然毅然用boost::thread,而且刚好asio的例程里面也有几行简单的代码,再网上随便一搜,还是很快上手的。这里记录下,我的小小的测试代码片段:

void simple_print(int* id)
{
    for (int i = 0; i < 5; i++)
    {
        cout << *id << ":" << i << endl;
        Sleep(3000);
    }
}



int main()
{
    int forcin = 0;
    int argc = 3;
    char* argv[5];
    vector<boost::shared_ptr<boost::thread>> thread_pool;

    for (int thread_num = 0; thread_num < 5; thread_num ++)
    {
        boost::shared_ptr<boost::thread> thread(new boost::thread(boost::bind(&simple_print, &thread_num)));
        thread_pool.push_back(thread);
//        thread->join();
        Sleep(2000);
    }

这里值得一提的是,貌似用boost的智能指针来包装一些东西这个做法 很值得提倡,具体原因我还不知道,不过应该会对内存的回收和使用效率有比较好的地方,所以这里可以看到就用实例化了智能指针的模板,用一个vector来当做一个线程池,然后每创建一个新的线程就跟它bind一个很简单的print函数,它就会开始执行了,跟java的线程实现方式比较类似,当然没有python那么简单易用,以下就是简单运行一下的图,冒号前面代表的是线程的编号吧,我特意用了2秒和3秒这两个错开的停顿时间,这样线程的效果就很明显了:

 

对了,现在有点明白那个thread.join()的作用了,比如这里如果将join也去掉注释的话,那它就会等某一个线程完,才会执行下一个语句,如果是单线程的时候,当然感觉不到这个效果,或者是,两个线程已经生成了,然后又将两个线程的join写在一起,那就根本没有效果,怪不得我之前没有注意到这个效果,好吧,挫逼了……

 

还有个更挫逼的问题需要记录下,菜鸟级的问题:不说了,说多了都是翔,指针和引用的关系:

void test_ptr(int* num)
{
    (*num)++;
    cout << *num << " :in the test_ptr" << endl;
}

    int test_num = 0;
    test_ptr(&test_num);

所以要注意server2的例程代码当中,是这样的,

 typedef boost::shared_ptr<boost::asio::io_service> io_service_ptr;
  typedef boost::shared_ptr<boost::asio::io_service::work> work_ptr;
/// The pool of io_services. std::vector<io_service_ptr> io_services_; /// The work that keeps the io_services running. std::vector<work_ptr> work_; /// The next io_service to use for a connection. std::size_t next_io_service_; };

Io_service_ptr是一个智能指针的vector,然后指针的意思就是这个vector里面存的都是每个ioservice对象的地址,所以那个:

 /// Get an io_service to use.
  boost::asio::io_service& get_io_service();

是返回一个指针所指向的值,用引用来表示,所以这里就用一个ioservice对象的引用来标示!!!!初始化的比如boost::asio::io_service& io_service表示一个对象的引用,然后就这样吧,传出引用,然后要收他的函数的函数也是对象引用的参数类型。

 

然后request_handler是server的一个私有对像,传进去的可以直接传对象,像这个connection的构造函数,第一个参数就是io_service的指针来的,从get_io_service那个函数中从vector中获得的,而第二个就是传进来一个requesthandler对象而已,但是它在函数的声明中是要引用的,所以也是会改变值的。

  explicit connection(boost::asio::io_service& io_service,
      request_handler& handler);

 

 

 

转载于:https://www.cnblogs.com/allen-tung/p/3415384.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值