0

Now,i used code :

UINT postThread(LPVOID pParam)
{
    CGA_SpikeDlg*p = (CGA_SpikeDlg*)pParam;
    p->RunTimer();
    return 0;
}
void CGA_SpikeDlg::threadNew()
{
    AfxBeginThread(postThread, this);
}

void CGA_SpikeDlg::RunTimer()
{
    SetTimer(1, 6000, NULL);
}

void task1(M_args Parameter_, double Mtime, double tempVB, double TimeStep, double m_I, int FlagParameter[], M_args_Bound Parameter_Bound[], int MaxGeneration, float gL, float C, const int POPULATION_SIZE, float crossver, float mutations, stringstream &strResult)
{
    solveGPU_cpp(Parameter_, Mtime, tempVB, TimeStep, m_I, FlagParameter, Parameter_Bound, MaxGeneration, gL, C, POPULATION_SIZE, crossver, mutations, strResult);
    //cout << "task1 says: " << endl;
}
void CGA_SpikeDlg::OnTimer(UINT_PTR nIDEvent)
{
    // TODO:  在此添加消息处理程序代码和/或调用默认值
    switch (nIDEvent)
    {
        case 1:   //定时器1处理函数,定时发送数据进行更新
        {   

            CString cstr((strResult.str()).c_str());
            //str.Format("%f", duration);
            m_result.SetWindowText(cstr);
            UpdateData(false);
            break;
        }
    }
    CDialogEx::OnTimer(nIDEvent);
}
void CGA_SpikeDlg::OnBnClickedButtonRun()
{
    // TODO:  在此添加控件通知处理程序代码
    UpdateData(true);
    threadNew();
    thread t1(task1, Parameter_, Mtime, tempVB, TimeStep, m_I, FlagParameter, Parameter_Bound, MaxGeneration, gL, C, POPULATION_SIZE, crossver, mutations, std::ref(strResult));
    t1.join();
}

I want to show the value of strResult on my EDIT. I want to see how it change when i run.But when i run,The window displays no response,After a period of time, it shows the final result,That's not what I want.

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
JIaminShen
  • 25
  • 5

1 Answers1

0

The thread is local variable and joining it cause the main thread to block and wait the helper thread t1 to finish.

Make the thread a pointer or shared_ptr, make it member if your dialog class make sure you join it in the destructor at least.

Like:

mThread = std::make_shared<std::thread>(task1, Parameter_, Mtime, tempVB, TimeStep, m_I, FlagParameter, Parameter_Bound, MaxGeneration, gL, C, POPULATION_SIZE, crossver, mutations, std::ref(strResult));

And ... you don't need a thread for the window timers.

UPDATE: Make the tread a member of the dialog:

std::stared_ptr<std::thread> mThread;

Pack all parameters in a struct or class:

struct Args
{
   M_args Parameter_;
   double Mtime;
   double tempVB;
   double TimeStep;
   double m_I;
   std::vector<int> FlagParameter;
   std::vector<M_args_Bound> Parameter_Bound;
   int MaxGeneration;
   float gL;
   float C;
   int POPULATION_SIZE;
   float crossver;
   float mutations;
};

Copy all data in the struct and pass it to the thread together with a reference to the strResult:

mThread = std::make_shared<std::thread>(Args, std::ref(strResult));

join in the destructor. Make sure you do no start the thread twice etc..

Mihayl
  • 3,821
  • 2
  • 13
  • 32
  • @ A A I used t1.detach() to replace t1.join() ,I got what i want.Thanks again. – JIaminShen Nov 15 '17 at 12:15
  • Also a solution, but you have to be careful to wait all your threads to finish. – Mihayl Nov 15 '17 at 12:16
  • @A A emm...if i use t1.detach() i found the window displays is ok,but The parameters of my solveGPU_cpp function are random numbers...so result is wrong...Do you have some ways to solve it? – JIaminShen Nov 15 '17 at 13:39
  • Place a breakpoint in `task1` and look the arguments in the debugger? – Mihayl Nov 15 '17 at 13:42
  • I pass the parameters run task1,and Output the parameters to the file in the function of the.Cu file.I find if use t1.join() is right, if use t1.detch() is not right. My parameter becomes a random value.why? – JIaminShen Nov 15 '17 at 14:02
  • My guess is that that parameters you passed were in the t1 object on the stack and are no more there when the tread starts. You can try this by putting a `sleep` between the thread and the detach. But would be better to move the thread as member. – Mihayl Nov 15 '17 at 14:09
  • @ A A ...I use sleep(1000), but it sometimes right ,sometimes not right, if I run a long time,At first it was right, and then it became wrong again – JIaminShen Nov 15 '17 at 14:28
  • The sleep is not a solution, it was just to test. You need to clean up an mive the thread object as member so it keeps all the arguments. The OS needs a time ti spawn a new thread and you cannot rely on sleep. – Mihayl Nov 15 '17 at 15:14
  • you means i need to let thread t1 to be a member of my Dlg. But my arguments is locals.Can u give some example? – JIaminShen Nov 16 '17 at 01:58
  • `auto mThread =std::make_shared(task1, Parameter_, Mtime, tempVB, TimeStep, m_I, FlagParameter, Parameter_Bound, MaxGeneration, gL, C, POPULATION_SIZE, crossver, mutations, std::ref(strResult));` if i use this, How can i post mThread to destructor,because my arguments only in this function,so i can't let mThread to be a member of my dlg – JIaminShen Nov 16 '17 at 03:23
  • Not `auto mThread` - add `std::thread mThread;` to your class. – Mihayl Nov 16 '17 at 06:24
  • But it looks like you need some of your local variables. At least `int FlagParameter[], M_args_Bound Parameter_Bound[]` are pointers, don't be fooled by the syntax, and `strResult` a reference. – Mihayl Nov 16 '17 at 06:32
  • If i use `std::thread mThread` to my class, `mThread = std::make_shared(task1, Parameter_, Mtime, tempVB, TimeStep, m_I, FlagParameter, Parameter_Bound, MaxGeneration, gL, C, POPULATION_SIZE, crossver, mutations, std::ref(strResult));` this code said not right ,i see Variable types of mThread are different – JIaminShen Nov 16 '17 at 12:13
  • yeah..i use it,and it looks like ok,but the result is not right, it looks like not get my values of arguments – JIaminShen Nov 16 '17 at 12:30
  • I would propose to start with something simple and debug. And as someone already pointed mark your answered questions – Mihayl Nov 16 '17 at 12:31
  • I debug my program,and i find that,if i add `mThread->join()` to function of OnBnClickedButtonRun(),the result is right ,but my ui will be doesn't respond,if i add `mThread->join()` to `CGA_SpikeDlg::~CGA_SpikeDlg() { mThread->join(); }` ,the result is wrong ,My parameters become random value,it can't get my right parameters. – JIaminShen Nov 16 '17 at 12:45
  • This means that you're using local variables. My proposal would be to pack all parameters in struct, make sure they are copied and pass it to thread. You already have too much parameters. – Mihayl Nov 16 '17 at 12:50
  • I define the structure outside the class,`struct threadInfo { struct M_args_Bound Parameter_Bound[5]; double Mtime;//ms double tempVB;//初值 double m_I;//电流 float gL; float C;//电容 int MaxGeneration; float crossver; float mutations; double TimeStep; struct M_args Parameter_; const int POPULATION_SIZE; int FlagParameter[5];//Na,K,KM,Kv,Ca }; ``threadInfo Info;` Compiler prompt :GA_SpikeDlg.cpp(72): error C2512: “threadInfo”: There is no default constructor available – JIaminShen Nov 16 '17 at 13:00
  • Remove the const from `const int POPULATION_SIZE;` – Mihayl Nov 16 '17 at 13:03
  • ...If i use `threadInfo Info` to be my parameter,it happend-- Visual Leak Detector detected 7 memory leaks (636 bytes). – JIaminShen Nov 16 '17 at 13:16
  • I've solved the memory leak, but the result is still wrong. I debug it now. – JIaminShen Nov 16 '17 at 13:28
  • I would like to ask how to post data from the solveGPU function to the DLG class – JIaminShen Nov 22 '17 at 08:50
  • There is a for loop in the soveGPU function, and I want to post the updated data back to the MFC class after each loop – JIaminShen Nov 22 '17 at 08:57
  • You have a typical producer/consumer. You can start with https://stackoverflow.com/a/9396587/8918119 or https://codereview.stackexchange.com/a/84116 or just look for C++ topics on the theme – Mihayl Nov 22 '17 at 08:59
  • I try it,and I encountered a lot of trouble,For example, I can not introduce header files in .cu, can I use like "postMessage" to send my message? – JIaminShen Nov 24 '17 at 02:34