简体   繁体   English

当正确使用结构指针作为线程函数的参数时,无法在结构内传递值?

[英]Can not pass values inside a struct, when use the struct pointer as an argument to a thread function correctly?

I wrote a very simply code to use C++11 thread.我写了一个非常简单的代码来使用 C++11 线程。 I found that if I use struct pointer as an argument for the threaded function, the value inside the struct can not be passed correctly.我发现如果我使用结构体指针作为线程函数的参数,结构体内部的值无法正确传递。 Please tell me where I did wrong.请告诉我我哪里做错了。 Thanks.谢谢。

#include<iostream>
#include<thread>
#include<mutex>

using namespace std;

typedef struct {
    int tid;
    int bbb;
} arguments;


void blahblah (void * args) {
    int tid1 = ((arguments*)args)->tid;
    int b = ((arguments*)args)->bbb;

    printf("the tid is %d, %d\n", tid1, b);
}


int main ()  {
    int n = 5;
    // thread * ThreadArray = (thread*)malloc(n * sizeof(thread));
    thread  ThreadArray[n]; 

    int tid = 0, bbb = 6;
    for (int i = 0; i < n; i++) {
        arguments args = {tid, bbb};
        tid++;
        bbb--;
        printf("the data inside %d, %d\n", args.tid, args.bbb);
        ThreadArray[i] = thread (blahblah, &args);
    }

    for (int i = 0; i < n; i++) {
        ThreadArray[i].join ();
    }
    return 1;
}

The result is like:结果是这样的:

the data inside 0, 6 
the data inside 1, 5 
the data inside 2, 4  
the data inside 3, 3 
the tid is 3, 3   
the tid is 3, 3
the tid is 4, 2
the data inside 4, 2   
the tid is 4, 2   
the tid is 4, 2

You're passing the address of a temporary arguments instance, so you have no guarantees it's valid when your thread tries to use it.您正在传递临时arguments实例的地址,因此当您的线程尝试使用它时,您无法保证它是有效的。 Instead, pass the args directly, since C++'s thread library supports arguments by value.相反,直接传递args ,因为 C++ 的线程库支持按值传递参数。

void blahblah (arguments args)
{
    printf("the tid is %d, %d\n", args.tid, args.bbb);
}

// ...

    for (int i = 0; i < n; i++)
    {
        arguments args = {tid, bbb};
        tid++;
        bbb--;
        printf("the data inside %d, %d\n", args.tid, args.bbb);
        ThreadArray[i] = thread (blahblah, args);
    }

Inside of your loop, you are passing a pointer to a local arguments variable that goes out of scope right after the std::thread constructor exits, so the memory is likely to be invalid by the time blahblah() tries to access it.在循环内部,您正在传递一个指向局部arguments变量的指针,该变量在std::thread构造函数退出后立即超出范围,因此在blahblah()尝试访问它时,内存可能无效。

You would have to declare the arguments memory outside of the loop so it stays around long enough for blahblah() to use it, eg:您必须在循环之外声明arguments内存,以便它保持足够长的时间以供blahblah()使用它,例如:

#include <thread>
#include <cstdio>
using namespace std;

struct arguments {
    int tid;
    int bbb;
};

void blahblah (arguments * args) {
    int tid1 = args->tid;
    int b = args->bbb;

    printf("the tid is %d, %d\n", tid1, b);
}

int main() {
    const int n = 5;

    thread ThreadArray[n]; 
    arguments args[n];

    int tid = 0, bbb = 6;
    for (int i = 0; i < n; i++) {
        args[i].tid = tid++;
        args[i].bbb = bbb--;
        printf("the data inside %d, %d\n", args[i].tid, args[i].bbb);
        ThreadArray[i] = thread(blahblah, &args[i]);
    }

    for (auto &t : ThreadArray) {
        t.join();
    }

    return 1;
}

Alternatively:或者:

#include <thread>
#include <memory>
#include <cstdio>
using namespace std;

struct arguments {
    int tid;
    int bbb;
};

void blahblah (unique_ptr<arguments> &args) {
    int tid1 = args->tid;
    int b = args->bbb;

    printf("the tid is %d, %d\n", tid1, b);
}

int main() {
    const int n = 5;

    thread ThreadArray[n]; 

    int tid = 0, bbb = 6;
    for (int i = 0; i < n; i++) {
        auto args = make_unique<arguments>();
        args->tid = tid++;
        args->bbb = bbb--;
        printf("the data inside %d, %d\n", args->tid, args->bbb);
        ThreadArray[i] = thread(blahblah, move(args));
    }

    for (auto &t : ThreadArray) {
        t.join();
    }

    return 1;
}

Or, you can pass the arguments by value instead:或者,您可以改为按值传递arguments

#include <thread>
#include <cstdio>
using namespace std;

struct arguments {
    int tid;
    int bbb;
};

void blahblah (arguments args) {
    int tid1 = args.tid;
    int b = args.bbb;

    printf("the tid is %d, %d\n", tid1, b);
}

int main() {
    const int n = 5;

    thread ThreadArray[n]; 

    int tid = 0, bbb = 6;
    for (int i = 0; i < n; i++) {
        arguments args{tid++, bbb--};
        printf("the data inside %d, %d\n", args.tid, args.bbb);
        ThreadArray[i] = thread(blahblah, args);
    }

    for (auto &t : ThreadArray) {
        t.join();
    }

    return 1;
}

Or, you caan simply get rid of arguments altogether, as std::thread supports functions with multiple parameters:或者,您可以完全摆脱arguments ,因为std::thread支持具有多个参数的函数:

#include <thread>
#include <cstdio>
using namespace std;

void blahblah (int tid, int bbb) {
    printf("the tid is %d, %d\n", tid, bbb);
}

int main() {
    const int n = 5;

    thread ThreadArray[n]; 

    int tid = 0, bbb = 6;
    for (int i = 0; i < n; i++) {
        printf("the data inside %d, %d\n", tid, bbb);
        ThreadArray[i] = thread(blahblah, tid++, bbb--);
    }

    for (auto &t : ThreadArray) {
        t.join();
    }

    return 1;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM