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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Потоки, с общим ресурсом, нужно проверив ресурс выполнить поток 
:(
    Опции темы
AGENTxXx
Дата 31.10.2011, 21:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Добрый вечер друзья!
Вот такая вот проблема:
Есть 2 потока. У каждого из них есть свой ресурс - число. После того как они создались, они должны сравнить свое число с общим числом(ресурсом). И после этого в общий ресурс записывается наименьшее число и далее идет условие:
если число у потока<=общему ресурсу (числу) то разрешить завершение его первым, а 2ой поток завершиться позже.

Наглядный пример задачи:
2 человека взяли в терминале карточки с номером 1 и 2, чтобы стоять в определенной очереди и оба подошли к кассе. Кассир посмотрел у себя по компу, что к нему зарегались 1 и 2. Но так как 1 это сделал раньше - то и обслужить его нужно в первую очередь.

А в задаче вижу проблему в том, что:
нужно как то по очереди проверить в начале число у первого потока, потом у второго, потом завершить поток с меньшим числом, а далее с большим.

Можете просто помочь в словесной форме, если это для вас проще)

P.S.: нужно реализовать обязательно с разными потоками. Как сделать все в одном потоке - это я и сам знаю)

всем ОГРОМНОЕ спасибо заранее!

Это сообщение отредактировал(а) AGENTxXx - 31.10.2011, 21:45
PM MAIL   Вверх
Дрон
Дата 3.11.2011, 16:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Java-ненавистник :)
****


Профиль
Группа: Участник Клуба
Сообщений: 3179
Регистрация: 29.12.2002
Где: Санкт-Петербург

Репутация: 24
Всего: 93



Я бы рад помочь -- люблю задачи про потоки -- но из описания совершенно непонятно, что же всё-таки нужно. Раз двадцать уже перечитал, и всё равно в сомнениях.

Есть подозрение, что нужна такая синхронизация потоков, при которой из ожидания эти потоки выходят в определённом порядке. Стандартных решений не знаю, но придумать можно.
А может быть задача в чём-то другом, поэтому гадать бессмысленно smile

Цитата(AGENTxXx @  31.10.2011,  22:44 Найти цитируемый пост)
2 человека взяли в терминале карточки с номером 1 и 2, чтобы стоять в определенной очереди и оба подошли к кассе. Кассир посмотрел у себя по компу, что к нему зарегались 1 и 2. Но так как 1 это сделал раньше - то и обслужить его нужно в первую очередь.

А что если #2 пришёл раньше, пока #1 где-то гулял? Или если #2 пришёл, а #1 решил в очереди вообще больше не стоять?


--------------------
Да. Именно так.
PM   Вверх
AGENTxXx
Дата 4.11.2011, 22:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



На счет последнего вопроса: если кто, то раньше своей очереди подошел, то тот все равно должен ждать, когда перед ним все пройдут.
Вот хороший пример про банк например: человек пошел в банк и снял деньги, потом он решил пойти в магазин и приобрести продукты и оплатить картой, но так как предыдущая транзакция в баке еще могла быть не обработана, то оплата в магазине может произойти только после того, как транзакция о снятии денег пройдет. 

В данном случае у каждого действия есть свой номер, и получается что снятие денек в банке, это 1, а оплата в магазине - это 2. Следовательно, если 1 еще не обработан, то 2му там еще и делать не че. А чтобы это учесть, у нас есть как раз общий ресурс, который говорит, до какого номера можно выполнять транзакцию.

Надеюсь стало чуть по яснее! 
PM MAIL   Вверх
Дрон
Дата 5.11.2011, 16:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Java-ненавистник :)
****


Профиль
Группа: Участник Клуба
Сообщений: 3179
Регистрация: 29.12.2002
Где: Санкт-Петербург

Репутация: 24
Всего: 93



Цитата
На счет последнего вопроса: если кто, то раньше своей очереди подошел, то тот все равно должен ждать, когда перед ним все пройдут.

Значит моё предположение было верным: ты хочешь, чтобы в какой-то момент потоки подождали друг друга и выполнились в определённом порядке.

Придумал я решение и не очень-то сложное, как оказалось Хотя может можно было и проще smile
Прикрепил к этому сообщению. Писал в Visual Studio 2010, но там только в одном месте используется LinQ, а так в целом и под .NET 2.0 можно запустить заменив эту строчку.

На словах идея такая: для того, чтобы потоки выполняли какой-то код по очереди можно использовать Mutex (можно и что-то другое, но у Mutex есть несколько полезных свойств).
Проблема в том, что Mutex просто разрешает выполняться первому пришедшему потоку, а нам нужен определённый порядок. Поэтому прежде чем использовать Mutex надо проверить, а действительно ли текущий поток -- самый приоритетный. Если нет, то поток ставится на паузу и ожидает каких-либо изменений в очереди.

Написано в достаточно общем виде с учётом возможности непредвиденного завершения потоков или случая больше двух потоков.

Вот основной код, без комментариев, если вдруг кому-то интересно, а качать архив не хочется smile
Код

        private readonly Dictionary<Thread, int> threadQ;
        private readonly Mutex mutex;

        public ThreadQueue()
        {
            threadQ = new Dictionary<Thread, int>();
            mutex = new Mutex(false);
        }

        public void AddToQueue(int priority)
        {
            lock (threadQ)
            {
                threadQ.Add(Thread.CurrentThread, priority);
                Monitor.PulseAll(threadQ);
            }
        }

        public void RemoveFromQueue()
        {
            lock (threadQ)
            {
                threadQ.Remove(Thread.CurrentThread);
                Monitor.PulseAll(threadQ);
            }
        }

        public void Wait()
        {
            while (true)
            {
                int current;
                int best;
                lock (threadQ)
                {
                    if (!threadQ.ContainsKey(Thread.CurrentThread))
                        throw new InvalidOperationException("Потока нет в очереди.");

                    current = threadQ[Thread.CurrentThread];
                    best = (from kvp in threadQ where kvp.Key.IsAlive select kvp.Value).Min();
                }
                
                if (current <= best)
                {
                    try { mutex.WaitOne(); }
                    catch (AbandonedMutexException) { }
                    RemoveFromQueue();
                    break;
                }
                else
                {
                    lock (threadQ)
                    {
                        Monitor.Wait(threadQ, 1000);
                    }
                }
            }
        }

        public void Continue()
        {
            try
            {
                mutex.ReleaseMutex();
            }
            catch(ApplicationException)
            {
                throw new InvalidOperationException("Continue можно вызывать только после Wait");
            }
        }


Это сообщение отредактировал(а) Дрон - 5.11.2011, 16:19

Присоединённый файл ( Кол-во скачиваний: 2 )
Присоединённый файл  ThreadQueue.zip 2,86 Kb


--------------------
Да. Именно так.
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

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


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

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


 




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


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

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