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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Mutex, Thread и WaitOne.Объясните как это работает 
V
    Опции темы
jonie
Дата 21.10.2008, 21:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 5613
Регистрация: 21.8.2005
Где: Владимир

Репутация: 22
Всего: 118



начну, пожалуй с кода
Код

    class Program
    {

        /// <summary>
        /// хорошее поведение.
        /// второй поток "вываливается" по таймауту, но он создается, а этого нехочется.
        /// </summary>
        static void foo()
        {

            Thread worker = new Thread(delegate()
            {
                Mutex syncObject1 = new Mutex(false, "SyncObject");
                if (syncObject1.WaitOne(100))
                {
                    Console.WriteLine("Enter to thread TID[{0}]", Thread.CurrentThread.ManagedThreadId);
                    Thread.Sleep(1000 * 10);
                    syncObject1.ReleaseMutex();
                    Console.WriteLine("ReleaseMutex TID[{0}]", Thread.CurrentThread.ManagedThreadId);
                }
                else
                {
                    Console.WriteLine("WaitOne timeout TID[{0}]", Thread.CurrentThread.ManagedThreadId);
                }

            });
            worker.Start();
        }

        /// <summary>
        /// плохое поведение.
        /// второй поток "попадает" в создание Thread-а
        /// </summary>
        static void foo2()
        {
            Mutex syncObject1 = new Mutex(false, "SyncObject1");
            if (syncObject1.WaitOne(100))
            {

                Thread worker = new Thread(delegate()
                {
                    Console.WriteLine("Enter to thread TID[{0}]", Thread.CurrentThread.ManagedThreadId);
                    Thread.Sleep(1000 * 10);
                    syncObject1.ReleaseMutex();
                    Console.WriteLine("ReleaseMutex TID[{0}]", Thread.CurrentThread.ManagedThreadId);

                });
                worker.Start();
            }
            else
            {
                Console.WriteLine("WaitOne timeout TID[{0}]", Thread.CurrentThread.ManagedThreadId);
            }
        }

        static void Main(string[] args)
        {
            for (int i = 0; i < 2; ++i)
            {
                foo();
            }
            Console.ReadLine();

            for (int i = 0; i < 2; ++i)
            {
                foo2();
            }
            Console.ReadLine();
        }
    }

в общем суть такая:
пусть у нас есть главный поток и некая функция, требующая запуска в отдельном потоке (например делает внутри себя Application.Start(new form())) - она у меня имитирована Sleep-ом на 10 секунд. 
При этом ставится условие: нельзя вызывать две функции одновременно (singleton).
Собственно вопрос: почему в foo() мьютекс ведет себя "как задумано", а в foo2() ведет себя не так как надо. Или (скорее всего) я недопонимаю сути мьютекстов....



--------------------
Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет...
PM MAIL Jabber   Вверх
PashaPash
Дата 21.10.2008, 23:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1233
Регистрация: 3.1.2008

Репутация: 13
Всего: 49



jonie, а что именно в foo2 должно помешать работать второму потоку? WaitOne в нем ты вызываешь из одного и того же - главного - потока. Этот поток после первого вызова WaitOne владеет мьютексом, и при повторных вызовах WaitOne просто продолжает владеть:
Цитата
You can use the WaitHandle..::.WaitOne method to request ownership of a mutex. The thread that owns a mutex can request the same mutex in repeated calls to WaitOne without blocking its execution. However, the thread must call the ReleaseMutex method the same number of times to release ownership of the mutex. The Mutex class enforces thread identity, so a mutex can be released only by the thread that acquired it. By contrast, the Semaphore class does not enforce thread identity.

А ReleaseMutex в потоке, который мьютексом не владеет, должен бросить ApplicationException, и бросает в твоем примере после 10 секунд.


--------------------
PM MAIL WWW   Вверх
jonie
Дата 21.10.2008, 23:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 5613
Регистрация: 21.8.2005
Где: Владимир

Репутация: 22
Всего: 118



Ааа... да, я затупил. спасибо.


--------------------
Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет...
PM MAIL Jabber   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

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


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

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


 




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


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

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