For last 48 hours, I have been trying to understand Multithreading and Socket Programming. I tried to implement socket programming and had success when not using multithreading. I am new to both of the topics and have raised 2-3 question on stack itself needing help on the same.
After googling a lot I found an article that explains Socket Programming and Multithreading, but I still have a lot of doubts in this article and got stuck at Figure 5 in the article.
private void AcceptConnections()
{
while (true)
{
// Accept a connection
Socket socket = _serverSocket.Accept();
ConnectionInfo connection = new ConnectionInfo();
connection.Socket = socket;
// Create the thread for the receives.
connection.Thread = new Thread(ProcessConnection);
connection.Thread.IsBackground = true;
connection.Thread.Start(connection);
// Store the socket
lock (_connections) _connections.Add(connection);
}
}
In the very last line you can see a lock has been taken and 3-4 lines above a delegate ProcessConnection is bound.
At this point, I am not clear how this lock is working. What is happening behind the scenes when the lock has taken? Why did the author use lock here? What would have happened if no lock was taken? How does the thread ProcessConnection work? What things are happening simultaneously?
I got confused with all these questions
I know there is a list of questions here, but it would be a great help if you could assist me in understanding the methodology of working with multithreading.
connection.Thread.Start(connection)starts a new thread with a call toProcessConnection, passingconnectionas thestateargument. Execution in the current thread continues immediately with the next line whileProcessConnectionis executed in the new thread.ProcessConnectiongets theSocketobject from theConnectionInfoobject passed to it byAcceptConnectionsand waits to receive data from the socket. When it receives data, it loops through all of the otherConnectionInfoobjects in theconnectionscollection and sends this data to each of them in sequence.So what’s running concurrently here? Well, we have the initial thread (call it Thread 0) executing
AcceptConnectionsin an endless loop. And then for each socket connection that we’ve accepted, we have a thread executingProcessConnection.The locks are needed because
ProcessConnectionusesforeachto loop through the known connections to send them data. If Thread 0 were to add a new connection to the collection while the collection is being enumerated in theforeach, anInvalidOperationExceptionwould be thrown inProcessConnection.The
lockdoes prevent the concurrency issue in this case, but it also causes a potential performance problem. It doesn’t only preventAcceptConnectionsfrom modifying the collection whileProcessConnectionis enumerating it. It also prevents any two threads executingProcessConnectionfrom enumerating the collection at the same time. A better choice in this case would be aReaderWriterLockSlimwhich would allow multiple threads to read the collection concurrently.