>  Q&A  >  본문

多线程 - C++11 std::thread这么使用为什么不对?

我写了这么一段代码,是想用B包裹一个线程,然后方便做一些操作,和关联一些变量。

class B
{
public:
    B(std::thread* a):t(a)
    {}
    static void run(B* s)
    {
        while(s->done)
        {
            //do something
        }
    }
private:
    bool done/*=false*/;
    std::thread* t;
};
class A
{
    A():
    a(new std::thread(&B::run,&a)),
    b(new std::thread(&B::run,&b)),
    c(new std::thread(&B::run,&c)),
    d(new std::thread(&B::run,&d))
    {}
private:
    B a;
    B b;
    B c;
    B d;
};

然后在VS2015下就出事了,函数B::run()传入的参数指针s的内容都是0xcdcdcdcd。但是看了一下,参数s的地址和申请时候的地址却是一样的,在主线程也查了一下这个地址发现却是有内容的,请问这是怎么回事呢?
或者说我的使用方法有误?正确的方法是什么样子的呢?

============

原本的问题是这样的,我有一个程序要在一个阶段要产生大量的片元数据来进行类似的插值计算,这些计算原本是在单线程的,后来发现消耗太高想把这些任务分给几个线程,让这些线程来完成这些任务,最后把结果合并起来。
我想的是给每个线程都搞了一个单生产者单消费者队列,主线程不断地根据负载把片元往这些线程里面装,线程不断消化,然后在一个指定的地方同步。
大概代码是这样的:
上面那个B是我用来包裹线程的类,我的思路是把队列和一些其他和这个线程相关的操作(同步、写入计算数据,写入计算终结信号等等)都封装到一起,然后程序开始的时候创建四个B对象,让这四个线程都跑起来,然后主线程可以调用B的方法不断地往线程中写入数据,最后可以使用同步操作来同步四个线程和主线程。
B::run就是我的执行函数。A类相当于是主线程初始化的类。

PHP中文网PHP中文网2764일 전984

모든 응답(5)나는 대답할 것이다

  • 怪我咯

    怪我咯2017-04-17 13:28:48

    因为在构造函数中传递了this指针

    회신하다
    0
  • 迷茫

    迷茫2017-04-17 13:28:48

    测试了你的代码,没有问题。
    我也是觉得你创建出来的A对象有可能析构了。。。
    看你发出来的代码不是原始代码吧。A的构造函数都是私有的
    还有就是记得new了内存 用完了要delete掉

    회신하다
    0
  • 伊谢尔伦

    伊谢尔伦2017-04-17 13:28:48

    你的主线程是不是没有调用子线程的join函数,这样主线程可能会先于子线程完成。然后子线程还在跑,主线程就已经调用了相关类的析构函数了?

    회신하다
    0
  • ringa_lee

    ringa_lee2017-04-17 13:28:48

    你是怎么查看的s的值?

    而且a(new std::thread(&B::run,&a))这种写法本身就有问题吧,B::run(&a)的调用可能在a的成员被构造之前,同时B::run(&a)用到了a.done。

    可以试试

    class B {
        public:
            B(): done(false), t([this](){run();}) {}
            void run() {while (done) /*do something*/;}
        private:
            bool done;
            std::thread t;
    };
    class A {
        private:
            B a, b, c, d;
    };

    회신하다
    0
  • 阿神

    阿神2017-04-17 13:28:48

    https://en.wikipedia.org/wiki/Magic_number_%28programming%29
    这是debug版本的CRT为了方便调试程序,在分配出来还没有初始化的时候提供的初始值。

    实际上,Windows上面还有更多这样的初始值,见下表:

    Uninitialized:
    BAADF00D Used by Microsoft's LocalAlloc/GlobalAlloc/HeapAlloc(LMEM_FIXED) to mark uninitialised allocated heap memory
    CCCCCCCC Used by Microsoft's C++ debugging runtime library to mark uninitialised stack memory
    CDCDCDCD Used by Microsoft's C++ debugging runtime library to mark uninitialised heap memory

    Freed:
    FEEEFEEE Used by Microsoft's LocalFree/GlobalFree/HeapFree() to mark freed heap memory
    DDDDDDDD Used by MicroQuill's SmartHeap and Microsoft's C++ debugging heap to mark freed heap memory

    No man's land:
    ABABABAB Used by Microsoft's LocalAlloc/GlobalAlloc/HeapAlloc() to mark "no man's land" guard bytes after allocated heap memory
    FDFDFDFD Used by Microsoft's C++ debugging heap to mark "no man's land" guard bytes before and after allocated heap memory

    회신하다
    0
  • 취소회신하다