Multithreading questions

Started by
1 comment, last by kurifu 22 years, 3 months ago
OK... so as some of you may have followed before.. I am using a blocking server to wait for an incoming connection and than start a new thread passing the socket information which will than use blocking sockets to handle information from the client. This will allow many people to be connected at once without interfering with other clients when one is waiting for incoming data. Now, if I create a class that handles encoding and decoding network messages, and make that a globlal in the parent thread, the child threads should still be capable of accessing that to my understanding, and a blocking call should not block any other of the threads right? What if the class is in a DLL. To my understanding since the application is sharing the dll code it saves a little on memory, and there should be no problems when each thread uses an instance of the class from the DLL file, right? I am not entirely sure of all the quirks of multithreading myself, so please bear with my questions. Gamedev''s AI Auto-Reply bot.
Gamedev's AI Auto-Reply bot.
Advertisement
It really depends on what this global class is. In order for every client to access it simultaneously, it either needs to be:
1) a simple class, meaning no state--no (consequential) class members. This is very possible to do as long as clients keep state (which would make it look very much like C programming), or if you have all the clients of the class have a handle and the class keeps the clients straight.
2) a synchronized class, so that shared resources are accessed serially from clients in different threads.

As far as saving space and code goes, the code you execute is all in one place no matter how many different things are calling it simultaneously. Your program does not create an entire new .exe copy of itself in memory every time you spin a thread. Instructions are instructions. This is why it''s so important to make functions re-entrant if you''re doing multithreaded programming--there is physically only one copy of the code, so any globals or statics can be affected by all threads.

I don''t think you save anything at all by using a DLL for multi-threaded verses a DLL for single-threaded. You get the costs and benefits of .DLLs, but nothing more. Certainly no magic savings for multithreaded programs.
If you made a class to handle coding/decoding the messages, you''d want an instance of that class for each thread that was coding/decoding messages. To share one would mean you''d have to step-lock the threads (very bad).

Using objects is a good start in making re-entrant functions - you also need to make certain you don''t use any static variables and don''t touch any globals (some of the C run-time stuff twiddles globals and/or TLS, so you need to be wary of using some of them, - like sprintf). That way you can call the functions from different threads (and in theory simutaneously as well) and it will still work.

If you touch the same data from two different threads, you need to lock/unlock the code that does so with a critical section.

This is the proto-typical example to demonstrate the nuaces of threading: Consider incrementing a variable from two different threads.

  ++m_iAccessCount;  


That''s not thread safe code. In order to increment an integer three instructions need to be executed:
mov eax, m_iAccessCountinc eaxmov m_iAccessCount, eax 

And you can be swapped out into a different thread inbetween any of those instructions. (Luckily most systems don''t allow op-code interauption - there''s some legacy systems that did though).

The soluion in this case is the use the function InterlockedIncrement(&m_iAccessCount), which is a function provided by Win32 just for this purpose.

In more complex data manipulation(and access!), you start by entering a crictial section and leave it when you''re done. This ensures that only one thread is use a peice of data at one time - otherwise one thread could read the data when a second thread was half-done updating it.

There are special cases that arise when you use primative that is the same size as the machine''s bus where the syncronization is automatic (called atomic syncronization). This would occur if you changed an integer or pointer _only_ on one thread but read it many (and only read it). This situation is unlikely to occur by itself, and takes maticulous planning to execute correctly - the advantage is that you can avoid the syncronization overhead under special circumstances. This is most useful on true multi-processor machines.


...
One pressing question that''s come-up at work is whether or not reading a double on a 586+ is atomic. It seems to me that it can''t be, as it needs to mov 64bits - but someone else tought the WIntel platform was garuanteed not to stop swap out during this time (it kept the bus locked for the whole transfer). Anyone _know?
- The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara

This topic is closed to new replies.

Advertisement