search

Home  >  Q&A  >  body text

多线程 - 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中文网2804 days ago1015

reply all(5)I'll reply

  • 怪我咯

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

    Because this pointer is passed in the constructor

    reply
    0
  • 迷茫

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

    Tested your code, no problem.
    I also think that the A object you created may have been destructed. . .
    See if the code you sent is not the original code. The constructors of A are all private
    Also, remember to use new memory and delete it when it is used up

    reply
    0
  • 伊谢尔伦

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

    Has your main thread not called the join function of the sub-thread? In this case, the main thread may complete before the sub-thread. Then the sub-thread is still running, and the main thread has already called the destructor of the relevant class?

    reply
    0
  • ringa_lee

    ringa_lee2017-04-17 13:28:48

    How did you check the value of s?

    And there is something wrong with the way a(new std::thread(&B::run,&a)) is written. B::run(&a) may be called before the members of a are constructed, and at the same time B: :run(&a) uses a.done.

    You can try it

    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;
    };

    reply
    0
  • 阿神

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

    https://en.wikipedia.org/wiki/Magic_number_%28programming%29
    This is the initial value provided by the debug version of CRT when it is allocated and not initialized in order to facilitate debugging the program.

    Actually, there are more such initial values ​​on Windows, see the table below:

    Uninitialized:
    BAADF00D Used by Microsoft's LocalAlloc/GlobalAlloc/HeapAlloc(LMEM_FIXED) to mark uninitialised allocated heap memory
    CCCCCCC Used by Microsoft's C++ debugging runtime library to mark uninitialised stack memory
    CDCDCDD 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

    reply
    0
  • Cancelreply