System.Threading.ThreadPool против семафора? - PullRequest
1 голос
/ 11 декабря 2011

Пример пула потоков:

public class Example {
public static void Main() {

    ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadProc)); //task 1
    ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadProc)); //task 2
    ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadProc)); //task 3

    Console.WriteLine("Main thread does some work, then sleeps.");

    Thread.Sleep(1000);

    Console.WriteLine("Main thread exits.");
}
static void ThreadProc(Object stateInfo) {
    Console.WriteLine("Hello from the thread pool.");
}
}

Пример семафора:

public class Example
{
private static Semaphore _pool;

private static int _padding;

public static void Main()
{
      _pool = new Semaphore(0, 3);

    // Create and start five numbered threads. 
    //
    for(int i = 1; i <= 5; i++)
    {
        Thread t = new Thread(new ParameterizedThreadStart(Worker));

        t.Start(i);
    }

    Thread.Sleep(500);

     Console.WriteLine("Main thread calls Release(3).");
    _pool.Release(3);

    Console.WriteLine("Main thread exits.");
}

private static void Worker(object num)
{
    Console.WriteLine("Thread {0} begins " +
        "and waits for the semaphore.", num);
    _pool.WaitOne();

    int padding = Interlocked.Add(ref _padding, 100);

    Console.WriteLine("Thread {0} enters the semaphore.", num);

    Thread.Sleep(1000 + padding);

    Console.WriteLine("Thread {0} releases the semaphore.", num);
    Console.WriteLine("Thread {0} previous semaphore count: {1}",
        num, _pool.Release());
}
}

Я полагаю, что это несколько затрат с семафором, чтобы создать 5 потоков в этом примере, но пул потоков используетвстроенный "пул потоков" (он будет использовать существующие потоки, такие как фоновый работник).Правильно ли это или больше к этому, есть ли реальное преимущество в использовании семафора, если вы просто хотите простой пул потоков, но скорость и производительность - это проблема?

Ответы [ 2 ]

6 голосов
/ 11 декабря 2011

Вы сравниваете яблоки и коровы.

ThreadPool позволяет использовать потоки для небольших задач. В нем отсутствует какой-либо удобный механизм рандеву (ваш сон (1000) - слабое решение этой проблемы).

Семафор - это способ синхронизации потоков, они могут быть потоками ThreadPool.

1 голос
/ 11 декабря 2011

Создавайте явные потоки и управляйте ими только в том случае, если вы ожидаете, что эти потоки будут работать долго, ИЛИ вам нужно, чтобы этот поток выполнялся как можно скорее .Даже тогда вам, вероятно, лучше использовать параллельную библиотеку задач и пометить задачу как долгосрочную.

Пул потоков поддерживает пул "живых" потоков, которые простаивают.Поэтому, когда вы звоните QueueUserWorkItem, весьма вероятно, что будет пустой поток, который может захватить вашу работу и уйти.Это не всегда так, но часто так и есть.При создании нового потока (т. Е. var t = new Thread(...)), всегда некоторые накладные расходы при запуске.

Кроме того, пул потоков позволяет установить максимальное количество потоков пула и управляет им.рабочая нагрузка.Таким образом, если вы разрешите четыре потока пула и поставите в очередь десять рабочих элементов, пул потоков обеспечит одновременную работу только четырех потоков пула.В некотором смысле вы можете думать о нем как о неявном семафоре, поскольку он не позволяет запускать более четырех потоков одновременно.Но он позволяет ставить в очередь столько, сколько вы хотите (в пределах некоторого большого системного предела).

...