Why don't they tell us this stuff...

Started by
4 comments, last by WebsiteWill 20 years, 8 months ago
OK. I''ve done some more testing of my threaded server and have narrowed down to location of my current bugs. Here is a breakdown of how things work. Class constructor calls a member function to create a certain number of threads (parameter passed in at object creation). The member function calls CreateThread() and passes in the address of a global function and a pointer to the class type as an argument. The global function does nothing more than recasts the parameter back to the original type and then calls the members LocalSend() function which is a member of the class and the function that should be doing all of the work. All of this works correctly, threads get made and function works pretty much. However, anytime I try to use one of the private members in the class with this function the program craps out. I thought initially that this was due to STL in some manner but I ran more tests and found that it simply occurrs whenever I try to use one of the private members such as this call: while(bKeepAlive == true) { cout << "SOME TEXT" << endl; } The program will error and die just after the conditional statement and never enters the code block or anything else. I''ve searched for help on classes with threads and pretty much anything I can think of and can''t find a reason for this. The other class members can access the private members just fine but NOT the function that is passed to the thread. I just don''t get why not. If I make local variables instead of using the members private to the class then everything works perfectly. This obviously is not a suitable option. I''ve tried critical sections around everywhere that I access private members but this doesn''t work either. I''m stumped and there doesn''t seem to be much good threading information to be had on the web. Any ideas? Webby
Advertisement
Class constructor calls a member function to create a certain number of threads (parameter passed in at object creation).

You''re calling a member function of a class that hasn''t been constructed yet?
I had some really simple programs error for me with Borland C++ on some computers at school. There was nothing wrong with the syntax at all. The problem was (I believe) that the compiler''s installation was corrupt, or perhaps Windows itself was in some way corrupt.
I am by no means an expert on programming; I''m merely trying to give you some possible explanations for simple errors such as that.
I hope this helps!
There isn''t much threading information on the web because its all covered decently by CS textbooks.

Use _beginthreadex(), not CreateThread(). Consult MSDN as to why.

And please, don''t blame the compiler. Thats the last thing we need here.
--God has paid us the intolerable compliment of loving us, in the deepest, most tragic, most inexorable sense.- C.S. Lewis
Well not exactly.

Short example.
class Net{public:   Net(int param1, int param2);   void NetSend();   void NetRecv();    void StartThreads(int param1, int param2); private:   vector<HANDLE>recvThreadVector;   vector<HANDLE> sendThreadVector;   queue<Packet*> sendQueue;   queue<Packet*> recvQueue;   bool logPackets;   bool keepThreadsAlive;};Net::Net(int param1, int param2){    //do all initialization here    logPackets = true;    keepThreadsAlive = true;    //do all other things and lastly call    StartThreads(param1, param2);}//NetSend will first check to see how many sending threads//are active. If multiple are active then it uses critical //sections where necessary to protect the information shared//between the other threads. None of the information assiciated//with the threads is available outside of this class so there//is no need for protection if only a single thread is active//though I might add it in just to be safe.void Net::NetSend(){   while(true)   {       if(!sendQueue.empty) /****ERRROR OCCURRS HERE*****/       {           //Do stuff to send the packet on top of queue       }   }}void Net::StartThreads{    DWORD dwThreadID;    Net* pSend = NULL;    HANDLE myHand;    for(int i=0; i<param1; i++)    {                  myHand = CreateThread(NULL, NULL, SendDispatch,                  reinterpret_cast< LPVOID >(pSend), 	          NULL, &dwThreadID);         sendThreadVector.push_back(myHand);    }    //NOTE SendDispatch is a globally declared function    //that receives a pointer to this class       //Repeat for loop for Recieve thread.}DWORD WINAPI SendDispatch(LPVOID lpParameter){    Net* pcBaseServer = reinterpret_cast<Net*>(lpParameter);    pcBaseServer->NetSend();    return 1;}int main(){     //Create a net object with 4 of each thread     Net myNet(4,4);      while(true)     {          //LOOP forever or until kill command is given     }       return 0;}


So you can see, my main program makes an instance of the class. Upon creation, the constructor will fill in all of the relevant information and then call the member function to start the threads. This all works flawlessly. The problem comes in the NetSend() function where I actually want to start accessing those private member variables for use. It falls apart there.
Like I stated before. If I override the private members with local variables inside of NetSend then everything works well.

Hope this clears it up a bit.

Thanks,
Webby

EDIT * Minor corrections.

[edited by - websitewill on August 10, 2003 9:46:13 PM]
Ahhh I got it solved.
Replaced the pSend in this call:

myHand = CreateThread(NULL, NULL, SendDispatch,
reinterpret_cast< LPVOID >(pSend),
NULL, &dwThreadID);

with the this pointer. I was sending in an uninitialized pointer and thus the program didn''t have access to the actual data. Errors gone now. Now I can find more bugs.

Good thing is I''m learning a hell of a lot by doing all of this.

Thanks for all the help guys,
Webby

This topic is closed to new replies.

Advertisement