Hi, I'm writing a large program but require Multithreading for this software. I've searched the web for just over an hour and now is just after midnight but still can't find anything simple. The only thing I saw that came close to what I need was at http://www.computersciencelab.com/MultithreadingTut1.htm but I can't even get that code to work. Basically I have 4 functions (same function but different parameters) and need each function to go into it's own thread making a total of 5 threads (5th thread being the GUI/main() function. The code I have for these functions are as follows:

myfunction(list,count,0,4);
myfunction(list,count,1,4);
myfunction(list,count,2,4);
myfunction(list,count,3,4);

So can somebody point me in the right direction as to how to get each of those functions to go into their own thread simultaneously and preferably with a lower priority than that of the GUI. Also the GUI is done in Microsoft Visual C++ 2008 with the CLR interface.
Any help is greatly appreciated and I'll check this topic in the morning when I wake up as it is now 12:42 at night. Thanks for any information/code provided. :)

Here is a simple example. The only reason it includes windows.h is because it uses the win32 api function Sleep() It will become more complicated if each of the threads must access the same global variable or common function. In that cast the threads have to be synchronized to avoid clashes while reading or writing at the same time.

#include <process.h>    /* _beginthread, _endthread */
#include <Windows.h>
#include <iostream>
using std::cout;

void MyThread( void *dummy );


int main()
{
    for(int i = 0; i < 5; i++)
    {
        _beginthread( MyThread, 0, (void *) (&i)  );

        /* Wait one second between loops. */
        Sleep( 1000L );
    }
}

void MyThread( void *param )
{
    int i = *(int *)param;
    cout << "Hello World from " << i << '\n';
}

Edited 6 Years Ago by Ancient Dragon: n/a

Comments
Great code in speedy time :=]]

@AD Since his application is on the CLR, it's probably easier to incorporate all of this as a BackgroundWorker class.

@OP Check out http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx and scroll about halfway down to "Examples" and make sure you have the C++ tab selected. It's not identical to what you are doing but you should be able to adapt it readily. I did not find a lot of information on C++/CLI threading out there, but if you look up the concept of delegates for C# you can adopt some of the information by changing the syntax (as it's all .NET under the hood).

(the code box starts out below the second screenshot, the one above that has nothing in it)

Edited 6 Years Ago by jonsca: n/a

Here is a simple example. The only reason it includes windows.h is because it uses the win32 api function Sleep() It will become more complicated if each of the threads must access the same global variable or common function. In that cast the threads have to be synchronized to avoid clashes while reading or writing at the same time.

#include <process.h>    /* _beginthread, _endthread */
#include <Windows.h>
#include <iostream>
using std::cout;

void MyThread( void *dummy );


int main()
{
    for(int i = 0; i < 5; i++)
    {
        _beginthread( MyThread, 0, (void *) (&i)  );

        /* Wait one second between loops. */
        Sleep( 1000L );
    }
}

void MyThread( void *param )
{
    int i = *(int *)param;
    cout << "Hello World from " << i << '\n';
}

That code looks good an all but I still have one question. How do I pass multiple parameters to the MyThread function? In my first post the function is defined as follows:

void myfunction(std::map <unsigned int, std::string> list,unsigned int count, 0, 4);

So could you please modify your code to allow these additional parameters as I don't have a clue.

I'm not 100% certain myself. There may be issues of having to marshal copy the map values (as they are an unmanaged type and not compatible with the managed code).

As far as how to pass parameters, I'm assuming that for example on the line: e->Result = ComputeFibonacci( safe_cast<Int32>(e->Argument), worker, e ); e->Argument would have to be some kind of data structure or ref class containing all of your parameters (see http://www.codeproject.com/Messages/2369118/Re-Custom-DoWorkEventArgs.aspx for a posting on custom event args), but again, I don't think that will work with the std::map. I wish I had more help to give you, but hopefully this gives you some more terms to search on.

Poke around C# sites that cover BackgroundWorker too. The only issue is translating the syntax (. being both :: and -> at times). The forum here will probably have some examples too.

I just found on the net the following code which I will try and embed and I'll let you know how it goes.

#include <process.h>    /* _beginthread, _endthread */
#include <Windows.h>
#include <iostream>
using std::cout;
 
typedef struct ST{ 
    int num; 
	int i;
    char* buf; 
}threadparam; 

void MyThread( threadparam* param )
{
	int i = (param)->i;
	int j = (param)->num;
    cout << "Hello World from " << i << " - " << j << '\n';
}

 
int main()
{
    for(int i = 0; i < 5; i++)
    {
		threadparam st;
		st.num = 6000;
		st.i = i;
        _beginthread((void(*)(void*))MyThread, 0,(void*)&st);
 
        /* Wait one second between loops. */
        Sleep( 1000L );
    }
}

I have nearly completed the code but still got one problem. In myfunction I have the following line:

resultbox->AppendText(std2sys("asdfasdf\n"));

However the resultbox (richtextbox) cannot be found due to the function being outside the Form1 class. Does anybody know how I can append to this field outside its class? Thanks.

If somebody can work out the answer that would be great but for now my patch might have to be to write to a text file from the thread functions and to get CLR to read the text file and update the fields accordingly. So if anybody has a better way I would love to hear it too.

Could somebody please explain to me what is wrong with the following code as I struggle to write to a file.

void file_put_contents(std::string data) {
    std::ofstream myfile ("datalog.tmp");
    if (myfile.is_open()){
        myfile << data;
        myfile.close();
        }
    }


std::string file_get_contents() {
    std::string line, res;
    std::ifstream myfile ("datalog.tmp");
    if (myfile.is_open()) {
        while (myfile.good()) {
            getline (myfile,line);
            res+=line;
            }
            myfile.close();
        }
    return res;
    }

See http://www.codeproject.com/Messages/3198006/Communicating-with-main-GUI-thread-from-worker-thr.aspx you can't write directly to the GUI thread as that could lock up your main application.

You cannot use an ofstream object. Any unmanaged types have to be transferred in between the unmanaged and managed parts through marshaling. Use a StreamWriter (http://msdn.microsoft.com/en-us/library/system.io.streamwriter.aspx) but as it says in the documentation, it is not thread-safe. There is a Textwriter::Synchronized available, but I've never used it.

Edited 6 Years Ago by jonsca: n/a

Comments
Thanks for the hand.

That's it. I give up. The machine has won the match point. C++ CLR is ever so hard so for this project I'll switch to the php-gtk language as it will make things ever so much more simple. After 12 intensive hours my head now hurts and perhaps switching languages will be the ideal solution. I'll reward rep points to those who help when I needed it and thanks for the great help.

Just abandon the CLR part. .NET and all this C# and managed C++ is useless and cumbersome. If your problem would have been just in straight C++, it would have been solved in minutes (using Boost.Thread), but only because of marshalling stuff and the evil .NET platform, you are stuck... another case of downsides outweighing the upsides in managed programming languages.

Here is an article about how to create managed threads in the current version of CLR. When I posted my example earlier today I didn't realize that the OP was using CLR.

This question has already been answered. Start a new discussion instead.