0

I have some problems with using _beginthreadex. How can I send function that was made by me to a thread? I am totally new to threads, its so silly question, but I can't handle it

//Function that I want to send to a thread

vector<int>F1(vector<int> A, vector<int> B, vector<int> C, vector<int> D, vector<vector<int>> MA, vector<vector<int>> MD) { 
    vector<int> ResVect;
    ResVect = plusVector(plusVector(A, plusVector(B, C)), VectMultMatr(D, MultMatr(MA, MD)));   
    return ResVect; 
}

//Thread funcF1

int main(){
    HANDLE funcF1, funcF2, funcF3;
    //////F1//////
    cout << "Task 1 starts" << endl;
    vector<int>A = createVect(1, 4);
    vector<int>B = createVect(1, 4);
    vector<int>C = createVect(1, 4);
    vector<int>D = createVect(1, 4);

    vector<vector<int>>MA = createMatrix(1, 4);
    vector<vector<int>>MD = createMatrix(1, 4);

    //vector<int>E = F1(A, B, C, D, MA, MD);
    funcF1 = (HANDLE)_beginthreadex(0, 0, &F1(A, B, C, D, MA, MD), 0, 0, 0);
}
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • 4
    Why not use the [standard C++ thread library](https://en.cppreference.com/w/cpp/thread)? (Where you'd want to use [srd::async()](https://en.cppreference.com/w/cpp/thread/async)) – Shawn Oct 16 '18 at 00:55
  • I assume that is a class requirement. Although it would be nice to see a clarification on that. – drescherjm Oct 16 '18 at 00:57
  • That should be `std::async()` unfortunately the 5 minute edit window is closed. – drescherjm Oct 16 '18 at 01:05
  • 2
    My recommendation - use standard C++ thread library. It it much less pain than the win32 threads – Chathura Dhanuska Oct 16 '18 at 01:05
  • @ChathuraDhanuska - really ? from my view win32 `CreateThread` more simply, and much more efficient compare std shell – RbMm Oct 16 '18 at 01:08
  • 1
    function for `_beginthread` or `CreateThread` must be exactly to signature declared. and via parameter to this function - you can pass pointer to class/struct where you hold all needed data/context for thread. of course data must be valid during thread lifetime. (if you say pass pointer to local data in creator stack variables - creator must not exit from func, until thread terminated) – RbMm Oct 16 '18 at 01:13
  • 2
    The advantage of `std::thread` is that you can pass parameters to the thread like any other function. – Jonathan Potter Oct 16 '18 at 01:13
  • @RbMm "*from my view win32 `CreateThread` more simply, and much more efficient compare std shell*" - except that MS's standard C runtime is not thread-safe and calling `CreateThread()` directly does not initialize the C runtime for multi-threading, whereas `_beginthread/ex()` does. See [Windows threading: _beginthread vs _beginthreadex vs CreateThread C++](https://stackoverflow.com/questions/331536/) – Remy Lebeau Oct 16 '18 at 01:39
  • @RemyLebeau - i mean compare `std::thread`. between call to `_beginthreadex` or `CreateThread` no big different compare signature or efficient. are we need or not need c runtime another question. however `_beginthreadex` not suspend caller thread and wait until child finish initialization, how `std::thred` doing – RbMm Oct 16 '18 at 01:46
  • A possible advantage of `std::async` is that C++ threads make it simpler to transport exceptions across thread boundaries. – Phil1970 Oct 16 '18 at 02:03
  • @Remy That documentation is long out of date – David Heffernan Oct 16 '18 at 06:32
  • Why not using std::thread - we need use exactly Win32, its demand of our teacher – Michael Phellps Oct 16 '18 at 18:24
  • @RbMm If the application is moving between different operating systems it is best to use std::thread – Chathura Dhanuska Oct 18 '18 at 01:36
  • @ChathuraDhanuska - i based on *winapi* tag – RbMm Oct 18 '18 at 08:24

1 Answers1

4

If you read the _beginthreadex documentation, you would see that the function you are passing in does not match the signature that _beginthreadex is expecting:

unsigned ( __stdcall *start_address )( void * )

To do what you are attempting, you need a function of that exact signature to wrap your real function.

Try something more like this instead:

vector<int> F1(vector<int> A, vector<int> B, vector<int> C, vector<int> D, vector<vector<int>> MA, vector<vector<int>> MD) {    
    return plusVector(plusVector(A, plusVector(B, C)), VectMultMatr(D, MultMatr(MA, MD)));  
}

struct myVecs {
    vector<int> A;
    vector<int> B;
    vector<int> C;
    vector<int> D;
    vector<vector<int>> MA;
    vector<vector<int>> MD;
};

unsigned __stdcall myThreadFunc(void *arg) {
    myVecs *vecs = (myVecs*) arg;
    vector<int> E = F1(vecs->A, vecs->B, vecs->C, vecs->D, vecs->MA, vecs->MD);
    // use E as needed...
    delete vecs;
    return 0;
}

int main(){
    HANDLE funcF1;

    //////F1//////
    cout << "Task 1 starts" << endl;

    myVecs *vecs = new myVecs;
    vecs->A = createVect(1, 4);
    vecs->B = createVect(1, 4);
    vecs->C = createVect(1, 4);
    vecs->D = createVect(1, 4);
    vecs->MA = createMatrix(1, 4);
    vecs->MD = createMatrix(1, 4);

    funcF1 = (HANDLE) _beginthreadex(0, 0, &myThreadFunc, vecs, 0, 0);
    if (func1 == 0) {
        // error handling...
        delete vecs;
    }

    // do other things as needed...

    // wait for thread to terminate before exiting the app...
    return 0;
}
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • 3
    While the answer is correct for the question, I would still recommend more standard C++ code. – Phil1970 Oct 16 '18 at 02:01
  • @Phil1970 perhaps, but the question isn't about C++-style threads, it is about C-style threads. We don't even know if the OP has C++11 available (not all developers do). – Remy Lebeau Oct 16 '18 at 02:06