C ++ функция создания потока с параметрами приводит к преобразованию ошибок - PullRequest
1 голос
/ 12 июля 2020

Я делаю свои первые шаги в многопоточности C ++ и столкнулся с проблемой. Я хотел бы достичь поставленных задач с параметрами, которые будут выполняться в отдельных потоках. Поиск ответов в Google не дал мне ответа.

Система, которую я использую, состоит из Windows 10 Pro и Code :: Blocks 20.3 с MinGW 17.1

Я создал простой пример чтобы прочувствовать это. Первый пример (один файл cpp) работает нормально. Однако у второго (в классе) есть ошибки сборки, хотя я использую тот же код.

Надеюсь, кто-то сможет объяснить причины, почему, и, надеюсь, покажет мне, как решить эту проблему.

Первый (рабочий) пример:

#include <windows.h>
#include <process.h>
#include <iostream>
#include <chrono>
#include <thread>

struct Param
{
    std::string param1;
};
unsigned Counter;

unsigned __stdcall DoSomething( void *ptr )
{
    std::cout << "In second thread...\n";

    Param *p_tmp = reinterpret_cast<Param*>(ptr);
    Param p_param = *p_tmp;
    std::string result = p_param.param1;

    while ( Counter < 1000 )
    {
        Counter++;
        std::cout << result << Counter << '\r';
        std::this_thread::sleep_for(std::chrono::milliseconds(2));
    }
    std::cout << std::endl;
    _endthreadex( 0 );

    return 0;
}

void CreateThread()
{
    HANDLE hThread;
    unsigned threadID;
    std::string result{"Count: "};
    Param param;
    param.param1 = "Count: ";

    std::cout << "Main thread\nCreating second thread...\n";

    // Create the second thread.
    hThread = (HANDLE)_beginthreadex( NULL, 0, &DoSomething, (void*)&param, 0, &threadID );

    // Wait until second thread terminates
    WaitForSingleObject( hThread, INFINITE );

    std::cout << "Returned to Main thread\nCounter should be 1000; it is-> "<< Counter << std::endl;
    // Destroy the thread object.
    CloseHandle( hThread );
}

int main()
{
   CreateThread();
}

Второй пример (в классе):

struct Param
{
    std::string param1;
};
unsigned Counter;

void CthreadFrame::CreateThread()
{
    HANDLE hThread;
    unsigned threadID;
    Param param;
    param.param1 = "Count: ";

    std::cout << "Main thread\nCreating second thread...\n";

    // Create the second thread
    hThread = (HANDLE)_beginthreadex( NULL, 0, &DoSomething, (void*)&param, 0, &threadID );
    // Wait for second thread to terminate
    WaitForSingleObject( hThread, INFINITE );

    std::cout << "Returned to Main thread\nCounter should be 1000; it is-> "<< Counter << std::endl;
    // Destroy the thread object.
    CloseHandle( hThread );

/* End of void CreateThread */
}

unsigned __stdcall CthreadFrame::DoSomething(void *ptr)
{
    std::cout << "In second thread...\n";

    Param *p_tmp = reinterpret_cast<Param*>(ptr);
    Param p_param = *p_tmp;
    std::string result = p_param.param1;

    while ( Counter < 1000 )
    {
        Counter++;
        std::cout << result << Counter << '\r';
        std::this_thread::sleep_for(std::chrono::milliseconds(2));
    }
    std::cout << std::endl;
    _endthreadex( 0 );

    return 0;
}

Сообщения сборки:

||=== Build: Debug in Cthread (compiler: GNU GCC Compiler) ===|
F:\Data\__C++\wxApps\Cthread\CthreadMain.cpp||In member function 'void CthreadFrame::CreateThread()':|
F:\Data\__C++\wxApps\Cthread\CthreadMain.cpp|114|error: cannot convert 'unsigned int (CthreadFrame::*)(void*)' to '_beginthreadex_proc_type' {aka 'unsigned int (*)(void*)'}|
f:\sdks\mingw-17.1\x86_64-w64-mingw32\include\process.h|37|note:   initializing argument 3 of 'uintptr_t _beginthreadex(void*, unsigned int, _beginthreadex_proc_type, void*, unsigned int, unsigned int*)'|
||=== Build failed: 1 error(s), 0 warning(s) (0 minute(s), 2 second(s)) ===|

Ответы [ 2 ]

0 голосов
/ 12 июля 2020

Спасибо, Георгий Фирсов.

Я бы никогда не подумал искать std :: msm_fn без вашей помощи.

Я изменил свой код на:

std::thread th(std::mem_fn(&CthreadFrame::DoSomething), std::ref(*this), (void *)&param );
th.join();

И это помогло. Теперь я могу передавать в функцию потока всевозможные переменные.

0 голосов
/ 12 июля 2020

Просто объявите свою функцию потока как stati c function:

class CthreadFrame
{
public:
    void Start() {
        m_hThread = (HANDLE)_beginthreadex(
            nullptr, 0, &CthreadFrame::DoSomething, 
            this /* store params here */, 0, &m_uThreadId
        );
    }

private:
    static unsigned __stdcall DoSomething(void*);

private:
    HANDLE m_hThread;
    unsigned m_uThreadId;
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...