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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Семафоры, Семафоры 
:(
    Опции темы
Sqwirl
Дата 22.12.2007, 22:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Не могли бы сказать как использовать семафоры в C#? (пример и т. п.)
PM MAIL   Вверх
QryStaL
Дата 22.12.2007, 23:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Intellectual feast
**


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

Репутация: 14
Всего: 32



Код

using System;
using System.Threading;

public class Example
{
    // A semaphore that simulates a limited resource pool.
    //
    private static Semaphore _pool;

    // A padding interval to make the output more orderly.
    private static int _padding;

    public static void Main()
    {
        // Create a semaphore that can satisfy up to three
        // concurrent requests. Use an initial count of zero,
        // so that the entire semaphore count is initially
        // owned by the main program thread.
        //
        _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));

            // Start the thread, passing the number.
            //
            t.Start(i);
        }

        // Wait for half a second, to allow all the
        // threads to start and to block on the semaphore.
        //
        Thread.Sleep(500);

        // The main thread starts out holding the entire
        // semaphore count. Calling Release(3) brings the 
        // semaphore count back to its maximum value, and
        // allows the waiting threads to enter the semaphore,
        // up to three at a time.
        //
        Console.WriteLine("Main thread calls Release(3).");
        _pool.Release(3);

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

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

        // A padding interval to make the output more orderly.
        int padding = Interlocked.Add(ref _padding, 100);

        Console.WriteLine("Thread {0} enters the semaphore.", num);
        
        // The thread's "work" consists of sleeping for 
        // about a second. Each thread "works" a little 
        // longer, just to make the output more orderly.
        //
        Thread.Sleep(1000 + padding);

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


 smile  smile 


--------------------
I don't need a reason being who I am...
PM MAIL ICQ   Вверх
Fieral
Дата 23.12.2007, 00:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



А как при этом решается проблема "занятого ожидания"?
--------------------
Если собака свернулась калачиком, значит будет дождь, а если сидит выпучив глаза, значит у неё запор.
PM MAIL   Вверх
mr.DUDA
Дата 23.12.2007, 10:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

Репутация: 110
Всего: 232



Цитата(Fieral @  22.12.2007,  23:54 Найти цитируемый пост)
занятого ожидания

А это что такое, разрешите полюбопытствовать ?

 smile 


--------------------
user posted image
PM MAIL WWW   Вверх
Fieral
Дата 23.12.2007, 15:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Ну, допустим у меня есть 2 процесса (или более) которые работают с одной областью памяти но поочереди.
Например по схеме ПРОДЮСЕР и ПОРТРЕБИЕЛЬ: 
Процессы запущенны параллельно и не должны входить в эту критическую область памяти (КОП) одновременно.
Сначала первый входит в КОП и пишет туда нечто, затем, когда он закончил, заходит второй и считывает из КОП.

Так вот чтобы они не мешали друг-другу я хочу использовать симафор S. Который принимает значение "0" когда должен в КОП зайти 1-й процесс,  значение "1" - когда он внутри, "2" - когда 1-й закончил и ожидается 2-й, значение "3" - второй процесс внутри и снова "0", когда 2-й закончил.

Процессы запущенные параллельно и имеют вид:

P1:  for(;;){  if (S==0){S:=1, <делать работу 1>, S:=2} }

P2:  for(;;){  if (S==2){S:=3, <делать работу 2>, S:=0} }




("for(;;)" - я написал, чтоб процесс работал поциклу)

Ну и проблема ("занятого ожидания") будет в том что процессы будут покругу гонять проверку if(S==?), поедая процессорное время - как это разрулить?

Это сообщение отредактировал(а) Fieral - 23.12.2007, 15:08
--------------------
Если собака свернулась калачиком, значит будет дождь, а если сидит выпучив глаза, значит у неё запор.
PM MAIL   Вверх
YuryS
Дата 23.12.2007, 15:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



На языке MC# (www.mcsharp.net ), в котором семафоры не нужны
(а точнее, заменены на более высокоуровневые средства),
решение может выглядеть так:
Код

using System;

public class Two_Workers   {

 public static void Main (String[] args ) {
 
  Two_Workers tw = new Two_Workers();
  
  tw.Worker ( 1 );
  tw.Worker ( 2 );
  
  tw.state1 ! ();  // Initial state
  
  Console.ReadKey();
  
 }
 
 public async Worker ( int myNumber ) {
 
  for ( ;; )
   if ( myNumber == 1 )
    getShared1 ? ();
   else
    getShared2 ? (); 
     
 }
 
 public handler getShared1 void() & channel state1 () {
  
  Console.WriteLine ( "Worker 1" );
  Thread.Sleep ( 1000 );
  state2 ! ();
  
 }
 
 public handler getShared2 void() & channel state2 () {

  Console.WriteLine ( "Worker 2" );
  Thread.Sleep ( 1000 );
  state1 ! ();

 }
  
 
}


Тест:
K:\Tmp>mcsc Two_Workers.mcs
MC# Compiler v 2.0.60 04-August-2007

K:\WINDOWS\system32\..\Microsoft.NET\Framework\v2.0.50727\csc.exe /r:"K:\Program
 Files\MC#\bin\mcsharp.dll"   "Two_Workers.cs"
Microsoft ® Visual C# 2005 Compiler version 8.00.50727.42
for Microsoft ® Windows ® 2005 Framework version 2.0.50727
Copyright © Microsoft Corporation 2001-2005. All rights reserved.

K:\Tmp>Two_Workers
Worker 1
Worker 2
Worker 1
Worker 2
Worker 1
Worker 2
Worker 1
Worker 2
PM MAIL   Вверх
Fieral
Дата 23.12.2007, 16:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Получается один процесс, поочерёдно пускает 2 процедуры.

У меня цепочка процессов, которые передают друг другу последовательно данные по этой же схеме.

user posted image

Где каждый процесс проверяет циклически данные на "не null"
и если "не null", то начинает читать, а если null то заново проверяет.

Как тогда быть с бесконечной проверкой на " не null"?
Вообще я видел в справочниках по OS, там это разруливается через списки заблокированных процессов. Я конечно могу и сам этот механизм реализовать, но думаю это опять окажется велосипедоизобреталтельством, что не есть хорошо. :(
 





Это сообщение отредактировал(а) Fieral - 23.12.2007, 16:44
--------------------
Если собака свернулась калачиком, значит будет дождь, а если сидит выпучив глаза, значит у неё запор.
PM MAIL   Вверх
mr.DUDA
Дата 23.12.2007, 20:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

Репутация: 110
Всего: 232



Fieral, можно к примеру завести именованный AutoResetEvent.


--------------------
user posted image
PM MAIL WWW   Вверх
Fieral
Дата 24.12.2007, 13:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



А что это такое?
--------------------
Если собака свернулась калачиком, значит будет дождь, а если сидит выпучив глаза, значит у неё запор.
PM MAIL   Вверх
YuryS
Дата 24.12.2007, 14:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата(Fieral @  23.12.2007,  16:39 Найти цитируемый пост)
Получается один процесс, поочерёдно пускает 2 процедуры.


Нет, не так. 
Главный процесс запускает 2 подчиненных процесса,
которые поочередно выполняют свою работу в зависимости от состояния системы.
У системы всего два состояния -
state1: работает первый процесс,
state2: работает второй процесс.

Организовать конвейер на языке MC# очень просто.

Пусть в конвейере должно работать N процессов,
тогда заводим N+1 специальных объектов BDChannel,
которые будут их связывать.
Процесс с номером i будет считывать данные из канала с номером i,
а выводить данные будет в канал с номером i+1.

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

Код

using System;

public class BDChannel   {

 public handler Receive String()  &   channel Send ( String s ) {
  return ( s );
 }
 
}

public class Conveyer   {

 public static int   M = 10;
 public static BDChannel[]  bdchannels;
 
 public static void Main ( String[] args )   {
 
  int   i;
  
  int   N = System.Convert.ToInt32 ( args [ 0 ] );
  
  bdchannels = new BDChannel [ N + 1 ];    // Create the channels
  for ( i = 0; i < N + 1; i++ )
   bdchannels [ i ] = new BDChannel();
   
  Conveyer conv = new Conveyer();
  
  for ( i = 0; i < N; i++ )   //  Run the workers
   conv.Worker ( i );
   
  for ( i = 0; i < M; i++ )  {
   bdchannels [ 0 ].Send ! ( " Message " + ( i + 1 ).ToString() + " : " );
   Console.WriteLine ( bdchannels [ N ].Receive ? () );
  }
  
 }
 
 public async Worker ( int myNumber )   {
 
  String   msg;
  
  for ( int i = 0; i < M; i++ )   {
   msg = (String) bdchannels [ myNumber ].Receive ? ();
   Thread.Sleep ( 100 );
   bdchannels [ myNumber + 1 ].Send ! ( msg + " + " + myNumber + " " );
  }
  
 }
 
}


K:\Tmp>mcsc Conveyer.mcs
MC# Compiler v 2.0.60 04-August-2007

K:\WINDOWS\system32\..\Microsoft.NET\Framework\v2.0.50727\csc.exe /r:"K:\Program
 Files\MC#\bin\mcsharp.dll"   "Conveyer.cs"
Microsoft ® Visual C# 2005 Compiler version 8.00.50727.42
for Microsoft ® Windows ® 2005 Framework version 2.0.50727
Copyright © Microsoft Corporation 2001-2005. All rights reserved.

K:\Tmp>Conveyer 10
 Message 1 :  + 0  + 1  + 2  + 3  + 4  + 5  + 6  + 7  + 8  + 9
 Message 2 :  + 0  + 1  + 2  + 3  + 4  + 5  + 6  + 7  + 8  + 9
 Message 3 :  + 0  + 1  + 2  + 3  + 4  + 5  + 6  + 7  + 8  + 9
 Message 4 :  + 0  + 1  + 2  + 3  + 4  + 5  + 6  + 7  + 8  + 9
 Message 5 :  + 0  + 1  + 2  + 3  + 4  + 5  + 6  + 7  + 8  + 9
 Message 6 :  + 0  + 1  + 2  + 3  + 4  + 5  + 6  + 7  + 8  + 9
 Message 7 :  + 0  + 1  + 2  + 3  + 4  + 5  + 6  + 7  + 8  + 9
 Message 8 :  + 0  + 1  + 2  + 3  + 4  + 5  + 6  + 7  + 8  + 9
 Message 9 :  + 0  + 1  + 2  + 3  + 4  + 5  + 6  + 7  + 8  + 9
 Message 10 :  + 0  + 1  + 2  + 3  + 4  + 5  + 6  + 7  + 8  + 9

K:\Tmp>
PM MAIL   Вверх
Fieral
Дата 24.12.2007, 16:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



То есть это какая-то хитро-библиотека, в которой уже все вопросы решены?

Можно ли обойтись стандартными средствами сишарпа?
--------------------
Если собака свернулась калачиком, значит будет дождь, а если сидит выпучив глаза, значит у неё запор.
PM MAIL   Вверх
YuryS
Дата 24.12.2007, 16:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата(Fieral @  24.12.2007,  16:11 Найти цитируемый пост)
То есть это какая-то хитро-библиотека, в которой уже все вопросы решены?


Во-первых, не "хитро"  smile , а очень простая и понятная.
Во-вторых, не "библиотека", а расширение стандартного C#
средствами параллельного (многопоточного) программирования.


Цитата(Fieral @  24.12.2007,  16:11 Найти цитируемый пост)
Можно ли обойтись стандартными средствами сишарпа? 


Это примерно тоже, что, программируя на C#, спрашивать - 
"а можно ли обойтись языком ассемблера?"
Ответ - можно, только только зачем мучиться на ассемблере,
если есть удобные высокоуровневые средства ?
PM MAIL   Вверх
Fieral
Дата 24.12.2007, 16:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



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

Вижу 2 варианта: 

1) Самому написать метод блокировки процессов по алгоритму из справочников об OS - тут я чётко могу понять сколько времени на это потрачу, как это работает и как этим пользоваться.

2) Освоить эту библиотеку, о которой я ничего не знаю. И в которой встречаются такие вещи как public handler Receive String()  &   channel Send ( String s ) и Receive ? (). Учитывая что я понятия не имею что такое handler, зачем нужен & и что значит ?. То я вполне обоснованно опасаюсь зарыться в дебри и потратьти на это неизвестное количество времени и не получить нужный результат. (программист я хреновый)

И пока что у меня выбор между ясно_чем и неизвестной библиотекой. Так что буду рад если поможете понять - стоит ли игра свеч. smile


--------------------
Если собака свернулась калачиком, значит будет дождь, а если сидит выпучив глаза, значит у неё запор.
PM MAIL   Вверх
YuryS
Дата 24.12.2007, 16:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Я бы сказал, что игра свеч стоит.
Во всяком случае, поможем по любым вопросам ...
Алгоритм взаимодействия процессов уже перед Вами.

Остальные вопросы пишите на [email protected]

PM MAIL   Вверх
Fieral
Дата 24.12.2007, 17:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Ну хорошо, я потом посмотрю подробнее документацию, а пока вот вопрос:

Код

private static object lock1 = new object;

public void ReadWrite(bool read, ref int value)
{
    lock(lock1)
    {
        if(read)
        {
            //read data
        }
        else
        {
             //write data
         }
    }
}


решит поставленную проблему? если "да" то чем это хуже использования MC#?

Это сообщение отредактировал(а) Fieral - 24.12.2007, 17:31
--------------------
Если собака свернулась калачиком, значит будет дождь, а если сидит выпучив глаза, значит у неё запор.
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

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


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

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


 




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


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

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