Как запустить несколько потоков одновременно в c#?

Всем привет!
У меня есть несколько потоков:
List<Thread> threads = new List<Thread>();
 
for (int i = 0; i < threadCount; i++)
{
    Thread thread = new Thread(Work);
    threads.Add(thread);
}

Необходимо запустить их одновременно (без помощи циклов), т.е. такое решение не устраивает:
foreach (var t in threads)
                t.Start();

Помогите, пожалуйста)
  • Вопрос задан
  • 12933 просмотра
Решения вопроса 1
@Sumor
С филосовской точки зрения всё равно потоки не стартуют одновременно, так как процессор-то один.
Но с точки зрения программирования можно предложить следующее решение с потоками-стартерами рабочих потоков.
class Program
{
static List<Thread> threads = new List<Thread>();   // Список потоков
static int threadCount = 10;                        // Число потоков
static ManualResetEvent startEvent = new ManualResetEvent(false);   // Событие для старта рабочих потоков
static volatile int starterCount = 0;               // Счётчик запущенных потоков. volatile показывает, что переменная будет изменяться в различных потоках и её не надо оптимизировать
static object LockObject = new object();            // Блокировка для изменения переменной starterCount

static void Main(string[] args)
{
    // Создаём пул потоков
    for (int i = 0; i < threadCount; i++)
    {
        Thread thread = new Thread(Work);
        threads.Add(thread);
    }
    // На старт — запускаем стартовые потоки и ждём их запуска
    foreach (var thread in threads)
        new Thread(Starting).Start(thread);
    while (starterCount < threadCount) Thread.Sleep(1);
    // Внимание — к этому моменту все стартовые потоки запустились и ожидают на WaitOne()
    Thread.Sleep(100);
    // Марш — установка события отпускает приостановленные потоки
    startEvent.Set();

    while (true) ;
}

static void Starting(object paramThread)
{
    lock (LockObject)
    {
        starterCount++;
    }
    startEvent.WaitOne();
    (paramThread as Thread).Start();            
}

static void Work()
{
    return;
}
}
Ответ написан
Пригласить эксперта
Ответы на вопрос 4
@gleb_kudr
Идиотское требование. Потому что даже если вы подпишите стартовать каждый поток по одному и тому же событию, они все равно будут вызываться синхронно.

Хотите нормального замера скорости чтобы на это не влиял старт потока? Элементарно - пишите таймстэмп из-под стартовавшего треда. Очевидно, что он выдаст вам значение только когда тред пройдет инициализацию. Потом просто выровняете свои треды по их таймстэмпам.

Ну или еще проще - запускаете потоки в самом начале, а потом делаете в каждом инвокейшн основной работы и считаете только это время.
Ответ написан
Комментировать
@CheeseMaster
Создаём несколько вспомогательных потоков, запускаем их последовательно. Суть этих потоков в том, чтобы проверять постоянно какую-нибудь определённую переменную, когда она изменится - запустить потоки с Work(). Меняем эту переменную, потоки "одновременно" запускают другие потоки.

Можно и не делать вспомогательных потоков, просто основную логику Work() не запускать до какого-либо события (например, изменения переменной).
Ответ написан
Комментировать
Fesor
@Fesor
Full-stack developer (Symfony, Angular)
ThreadPool не подойдет?
Ответ написан
Комментировать
Используйте Task Parralel Library. Отличное новое API для многопоточности. Просто, гибко, выразительно
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы