title: A critical section inside or outside a thread class is better? [Example inside]
body: <p>I have several threads (Providers), that are used by other threads (Workers) on concurrent basis.</p>
  
  <p>Several threads means severan critical sections according to threads.</p>
  
  <p>Is it impossble to place a critical section variable inside a thread class, or its better to hold separate array for critical section of each thread that needs to be concurrently accessed?</p>
  
  <p>Or there is a better practice?</p>
  
  <p>UPD: a bit explanation.</p>
  
  <p>Process flow is: </p>
  
  <ol>
  <li>Worker loads a pool of data to its self </li>
  <li>In cycle of own pool of data a Worker try to gain access to a Provider</li>
  <li>Worker gains access to Provider -> </li>
  <li>Worker locks it -> </li>
  <li>Worker posts data to Provider from own pool -> </li>
  <li>Provider start doing a job -> </li>
  <li>When job is done Provider sends event to Worker -> </li>
  <li>Worker gets a result -> </li>
  <li>Worker release lock -></li>
  <li>Goto 2 or exit if last data from pool was processed</li>
  </ol>
  
  <p>This actually works fine in a real situation with a very good outcome.
  But the problem is when I need to kill one of the Providers. </p>
  
  <p>If a critical section inside a Provider class, then its possible to get access violation once a Worker already entered CS and waiting for unlock and a provider is not really terminated yet, but terminated next step.</p>
  
  <pre><code>if not Provider.Terminated then
     Provider.CS.Enter;  //This is a place where AV occurs.
  Provider.PostData(Worker.Data);
  Provider.StartJob;
  WaitForSingleObject(Provider.EventJobIsDone, 30000);
  Provider.CS.Leave; //or here 
  </code></pre>
  
  <p>If I have to place CS outside - how it is better to do this and to test that a provider is terminated?</p>
  
  <p>Several Providers and many Workers, that are created / terminated at any time and should work together. There is no option, that one Worker process all its pool of data while others are waiting. Each Worker do one iteration and then waits while other Workers do the same, then again it do next iteration then again waits while others do the same and so on until all pools are proccessed and Workers are terminated (each on its own time, when pool is finished).</p>
  
  <p>Each iteration of Worker and result it gets influence what Provider would be chosen for that Worker next time.</p>
  
  <p>And again - this works fine in real conditions and no stucks happen. Very fast and quite as it is expected to work. </p>
  
  <p><strong>Example</strong></p>
  
  <p>A rough example.</p>
  
  <p>You have Worker threads, that load a pool of data from DB. There are different DBs, not only one. Each item - is a heavy picture 0.1Mb-10Mb - you never know before. Imagine each Worker has 100-5000 items to be processed - you need to convert it to a lesser picture or do some other process. You never know how many items there would be in any next Worker thread. It could be 10, 1000, 5000, more or less. Whenever a Worker thread is started - there should be no timeout for a new Worker thread to start processing its first item from data pool, because it's a waste of time that costs.</p>
  
  <p>You have 10 Providers, that are connected to 10 machines on the local network. Those machines do all the work you need remotely. (a rough example, please)</p>
  
  <p>You should balance (the real strategy is more complex and depends on the actual data - it's similar to: is it a JPG, TIFF, PNG, BMP or whatever format, but simply please think of balance) traffic among all the Providers correctly. To do this you should count the quantity of processed data and decide each iteration where to put next Worker call - to Provider1,2,3...or 10. Besides you need to return a result immediately to the calling Worker, because a Worker should give an immediate report, write a flag to DB (only Worker knows which DB) that data is processed (!important) and so on.</p>
  
  <p>That's are the conditions.
  In brief:</p>
  
  <ul>
  <li>10-50 Workers at a time with 100-5000 items</li>
  <li>Workers are started and finished on their own</li>
  <li>You can't do a prognosis how many Workers there would be at any time</li>
  <li>Service is working 24/7 and ready to process data</li>
  <li>10 Providers, each is a connection to a machine on the network</li>
  <li>A new Worker should as soon as possible start processing its data </li>
  <li>A need to balance traffic among Providers on-the-fly</li>
  <li>Amount of processed data thru each Provider affects the decision to choose next Provider for a next data process.</li>
  <li>Worker should always get a result and update data to DB</li>
  <li>Suddenly you are about to terminate a Provider</li>
  <li>Some Workers already waiting to process data with this one Provider</li>
  </ul>
  
  <p>How to tell the Workers to stop waiting and when they are unfreezed - how to avoid Access violation that is pretty sure may occur on the next step in Worker flow (which is presented in the code in above).</p>