Модераторы: Partizan, gambit
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Semaphore, счетчик превышает макс. доп. значение 
:(
    Опции темы
W1zArD
Дата 14.2.2011, 07:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 285
Регистрация: 29.1.2006

Репутация: нет
Всего: 3



Всем привет. Столкнулся со следующей проблемой.

Прочел вот тут про семафор.
Цитирую:
Цитата
Semaphore похож на ночной клуб – он имеет определенную вместимость, которую обеспечивает вышибала. После заполнения никто уже не может войти в ночной клуб, очередь образуется снаружи. Далее, если один человек покидает клуб, один из начала очереди может пройти внутрь. Конструктор Semaphore принимает минимум два параметра – число еще доступных мест и общую вместимость ночного клуба.


Решил покопать все это. Задачей было примерно следующее:
Цитата
Запустить N потоков и выполнять задачу, как только поток завершает работу, запускается следующий.


написал следующее:
Код
using System;
using System.Threading;

namespace ThreadTest
{
    class Program
    {
        private const int Max = 10;

        //10 потоков, после блокируем
        static Semaphore _sem = new Semaphore(Max, Max);
        static Random _rnd = new Random();
        static int _threadCount;

        static void Main(string[] args)
        {
            while (true)
            {
                if (_threadCount == Max)
                {
                    _sem.WaitOne();
                }
                new Thread(Task).Start();
            }
        }

        static void Task()
        {
            try
            {
                Interlocked.Increment(ref _threadCount);
                var i = _rnd.Next(100)*1000;
                Console.WriteLine("Thread {0} working", Thread.CurrentThread.ManagedThreadId);
                Thread.Sleep(i);
                Console.WriteLine("Thread {0} complete. Sleep: {1}", Thread.CurrentThread.ManagedThreadId, i);
            }
            finally
            {
                Interlocked.Decrement(ref _threadCount);
                _sem.Release(1);
            }
        }
    }
}


но тут возникла проблема.
Потоки создаются друг за другом, примерно это выводится в консоль (совсем не то, что ожидалось):
Цитата
Thread 3 working
Thread 4 working
Thread 5 working
Thread 6 working
Thread 7 working
Thread 8 working
Thread 9 working
Thread 10 working
Thread 11 working
Thread 12 working
Thread 13 working
Thread 14 working
Thread 15 working
Thread 16 working
Thread 17 working
...
Thread 1293 complete. Sleep: 2000
Thread 1305 complete. Sleep: 2000

+SemaphoreFullException Добавление указанного счетчика к семафору приведет к превышению максимального значения.

Что не правильно? :(
PM   Вверх
W1zArD
Дата 14.2.2011, 13:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 285
Регистрация: 29.1.2006

Репутация: нет
Всего: 3



стоп. Тут я погорячился, попробовал сделать вот так:

Код

using System;
using System.Threading;

namespace ThreadTest
{
    class Program
    {
        private const int Max = 10;
        static Random _rnd = new Random();
        static int _counter;
        static ManualResetEvent _event = new ManualResetEvent(false);
        
        static void Main(string[] args)
        {
            while (true)
            {
                if (_counter == Max)
                {
                    _event.WaitOne();
                }
                new Thread(Task).Start();
            }
        }

        static void Task()
        {
            try
            {
                Interlocked.Increment(ref _counter);
                var i = _rnd.Next(10) * 1000;
                Console.WriteLine("Thread {0} working", Thread.CurrentThread.ManagedThreadId);
                Thread.Sleep(i);
                Console.WriteLine("Thread {0} complete. Sleep: {1}", Thread.CurrentThread.ManagedThreadId, i);
            }
            finally
            {
                Interlocked.Decrement(ref _counter);
                _event.Set();
            }
        }
    }
}


В итоге консоль просто пестрит сообщениями и создается порядка 500 потоков...
PM   Вверх
neic
Дата 16.2.2011, 02:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 839
Регистрация: 28.1.2007

Репутация: нет
Всего: 7



А где у тебя _counter инкрементируется?
PM MAIL WWW ICQ Skype   Вверх
W1zArD
Дата 16.2.2011, 17:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 285
Регистрация: 29.1.2006

Репутация: нет
Всего: 3



Код

class Program
    {
        private const int Max = 10;
        static Random _rnd = new Random();
        static int _counter;
        static AutoResetEvent _event = new AutoResetEvent(false);

        static void Main(string[] args)
        {
            while (true)
            {
                if (_counter >= Max)
                {
                    _event.WaitOne();
                }
                Interlocked.Increment(ref _counter);
                ThreadPool.QueueUserWorkItem(a => Task());
            }
        }

        static void Task()
        {
            try
            {
                var i = _rnd.Next(10) * 1000;
                Console.WriteLine("Thread {0} working", Thread.CurrentThread.ManagedThreadId);
                Thread.Sleep(i);
                Console.WriteLine("Thread {0} complete. Sleep: {1}", Thread.CurrentThread.ManagedThreadId, i);
            }
            finally
            {
                Interlocked.Decrement(ref _counter);
                _event.Set();
            }
        }
    }


все, сделал.
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
Partizan
PashaPash

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, Partizan, PashaPash.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | .NET для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.1155 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.