Многопоточный тупик в самодельном пуле потоков на C#C#

Место общения программистов C#
Ответить
Anonymous
 Многопоточный тупик в самодельном пуле потоков на C#

Сообщение Anonymous »

Я прошу прощения за то, что публикую здесь этот длинный код, но у меня нет другого способа помочь вам воспроизвести мою проблему. Код, который я вам даю, конечно, представляет собой миниатюру того, что я использую.
Я знаю, что мог бы использовать QueueUserWorkItem, и использовал его до недавнего времени, но понял, что мои потоки настолько коротки, что мой метод ThreadDispatcher не запускал второй до завершения первого. Итак, я пытаюсь понять, быстрее ли этот способ сделать это или нет. Проблема в том, что у меня возникла тупиковая ситуация, и я действительно не могу понять, почему.
Я публикую код, который вы можете напрямую скомпилировать и воспроизвести проблему.

Код: Выделить всё

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;

namespace TestWhatever
{
public class Program
{
static MyClass ThisClass = new MyClass();
static void Main()
{
ThisClass.Start();
for (int Cnt = 0; Cnt < 5; Cnt++)
{
Console.WriteLine("Launching Frame " + Cnt);
ThisClass.Update();//Frames loop
}
}
}

public class MyClass
{
Random MyRandom = new Random();

public static object _MultiDispatcherLocker = new object();
public static bool MonoDispacherThreadLocked = true;
public static bool MultiDispacherThreadLocked = true;
// Thread pool in multithreading case
private int MaxThreadsInParallel = 5;
private static int MaxNumOfPool = 20;
private Thread[] ThreadsPool;
public static object _ThreadLockerList;
private Func[] ThreadFunctions;
public bool[] ThreadLockedBools = Enumerable.Repeat(true, MaxNumOfPool).ToArray();

public void Start()
{
StartThreads();
}

public void Update()
{

lock (_MultiDispatcherLocker)
{
MultiDispacherThreadLocked = false;
Monitor.Pulse(_MultiDispatcherLocker);
}
Thread.Sleep(1000);
}

private void StartThreads()
{
ThreadsPool = new Thread[MaxNumOfPool];
_ThreadLockerList = new object();
ThreadFunctions = new Func[MaxNumOfPool];
ThreadLockedBools = new bool[MaxNumOfPool];

for (int Cnt = 0; Cnt < MaxNumOfPool; Cnt++)
{
Console.WriteLine("Preparing ThreadID: " + Cnt);
ThreadLockedBools[Cnt] = true;
ThreadsPool[Cnt] = new Thread(new ParameterizedThreadStart(LaunchThread));
ThreadsPool[Cnt].Start(Cnt);
}

Thread ThreadedMainThread = new Thread(new ThreadStart(ThreadDispatcher));
ThreadedMainThread.Start();
ThreadedMainThread.Priority = System.Threading.ThreadPriority.Highest;
}

private void LaunchThread(object iThreadID)
{
int ThreadID = (int)iThreadID;
lock (_ThreadLockerList)
{
while (ThreadLockedBools[ThreadID])
Monitor.Wait(_ThreadLockerList);
}
while (true)
{
Console.WriteLine("Starting ThreadID: " + ThreadID);
ThreadFunctions[ThreadID]();
Console.WriteLine("Ending ThreadID: " + ThreadID);
lock (_MultiDispatcherLocker)
{
ThreadLockedBools[ThreadID] = true;
MultiDispacherThreadLocked = false;
Monitor.Pulse(_MultiDispatcherLocker);
}
lock (_ThreadLockerList)
{
Console.WriteLine("Blocking ThreadID: " + ThreadID);
while (ThreadLockedBools[ThreadID])
Monitor.Wait(_ThreadLockerList);
}
}
}

private void ThreadDispatcher()//object Obj)
{
lock (_MultiDispatcherLocker)
{
while (MultiDispacherThreadLocked)
Monitor.Wait(_MultiDispatcherLocker);
}
while (true)
{

for (int Cnt = 0; Cnt < 20; Cnt++)//Threads loop
{

if (RunningThreads() < MaxThreadsInParallel)
{
int CurrIntTest = MyRandom.Next(100000, 10000000);

int ThreadID = GetNextEmptyThread();

ThreadFunctions[ThreadID] = () => { MyMethodInThread(CurrIntTest); return null;  };
lock (_ThreadLockerList)
{
ThreadLockedBools[ThreadID] = false;
Monitor.Pulse(_ThreadLockerList);
}
}
else//wait until someone ends
{
lock (_MultiDispatcherLocker)
{
while (MultiDispacherThreadLocked)
{
Monitor.Wait(_MultiDispatcherLocker);
}
}
}
}

lock (_MultiDispatcherLocker)
{
MultiDispacherThreadLocked = true;
while (MultiDispacherThreadLocked)
Monitor.Wait(_MultiDispatcherLocker);
}
}
}

private void MyMethodInThread(int Counter)
{
List MyDummy = new List();
for (int Cnt = 0; Cnt < Counter; Cnt++) MyDummy.Add("Dummy");
}

private int RunningThreads()
{
int ToReturn = 0;
for (int Cnt = 0; Cnt < MaxThreadsInParallel; Cnt++)
{
if (!ThreadLockedBools[Cnt] || ThreadsPool[Cnt].ThreadState != System.Threading.ThreadState.WaitSleepJoin)
ToReturn++;
}
return ToReturn;
}

private int GetNextEmptyThread()
{
for (int Cnt = 0; Cnt < MaxThreadsInParallel; Cnt++)
{
if (ThreadLockedBools[Cnt] && ThreadsPool[Cnt].ThreadState == System.Threading.ThreadState.WaitSleepJoin)
return Cnt;
}
return -1;
}

}
}
было бы здорово, если бы вы мне с этим помогли.

Подробнее здесь: https://stackoverflow.com/questions/358 ... in-c-sharp
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»