Deutsch

Задачка на синхронизацию

1019  1 2 все
Fleitist прохожий23.02.24 20:19
23.02.24 20:19 

1. Имеется некий класс, содержащий пять функций A, B, C, D, E. Первые две функции A и B могут работать параллельно. Все остальные комбинации функций должны быть синхронизованы, т.е. если выполняется C, то D блокируется и ожидает. Это касается также таких комбинаций, как-то АС, СА, AD, DA, AE, EA, BC, CB и т.п.


2. Задачу можно обобщить до любого количества параллелизуемых, а также их подмножеств. Синхронизируемые также не ограничены в росте.


Реальная задача из практики.

#1 
AlexNek патриот23.02.24 21:48
AlexNek
NEW 23.02.24 21:48 
в ответ Fleitist 23.02.24 20:19
Fleitist прохожий23.02.24 21:59
NEW 23.02.24 21:59 
в ответ AlexNek 23.02.24 21:48

Не знаю в чем проблема. В реализации задачи согласно ее условиям?

#3 
AlexNek патриот23.02.24 22:07
AlexNek
NEW 23.02.24 22:07 
в ответ Fleitist 23.02.24 21:59, Последний раз изменено 23.02.24 22:13 (AlexNek)
В реализации задачи согласно ее условиям

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

Для С шарпа все решения по ссылкам, для остальных подобных языков принципы аналогичны.

Для вашего случая добавляется просто еще одно условие синхронизации.

#4 
Fleitist прохожий23.02.24 22:40
NEW 23.02.24 22:40 
в ответ AlexNek 23.02.24 22:07
ну так это ваша проблема решить задачу

Так я ж не против, хотелось услышать другие мнения. Вы вот написали.

тогда можно и спрашивать

Спасибо, буду теперь знать, что можно и что нельзя.

#5 
AlexNek патриот23.02.24 23:04
AlexNek
NEW 23.02.24 23:04 
в ответ Fleitist 23.02.24 22:40
теперь знать, что можно и что нельзя.

Не совсем верное толкование.

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

В данном случае, решать учебную задачку за вас здесь никто не будет.

Но вам предстоит решить две проблемы

1. Определить текущее состояние класса и его соотношение с вызываемой функцией. Иначе говоря, решить - нужно использовать синхронизацию или нет.

2. Как синхронизировать вызов функции?


Попробуйте вначале шаг 2, когда любую функцию нужно синхронизировать.

Затем сделайте класс для шага 1, хотя возможно это будет сложно для вас, тогда делайте всё по месту.

#6 
Fleitist прохожий23.02.24 23:47
NEW 23.02.24 23:47 
в ответ AlexNek 23.02.24 23:04

Давайте попробуем пройтись по шагам. В посте первом условия задачи сформулированы в достаточной степени формально, без отвлечений на детали технических реализаций. Попробуйте прочесть. Когда осознаете поставленную задачу, попробуйте ее реализовать на любом доступном вам языке, например C# - без разницы. Вы вправе применять любые средства синхронизации, некоторые из которых вы любезно предоставили по вашим ссылкам. Когда вы доберетесь до проблем с реализацией (надеюсь) и еще раз перечитаете условия задачи, то вы можете тогда ответить. Осветите проблематику возможной реализации, не забыв при этом упомянуть неполноту по Гёделю перечисленных вами средств. Конечно же, не забудьте упомянуть оные в списке рекомендуемой литературы, как любезно предоставленные вами вышеизложенные(зачеркнуто) вышеприведенные ссылки. Думаю только и именно тогда, коллега, возникнет импульс к дискурсу, чего и пытался достигнуть ваш покорный слуга.

#7 
Murr патриот24.02.24 02:31
Murr
NEW 24.02.24 02:31 
в ответ Fleitist 23.02.24 23:47

Когда осознаете поставленную задачу

-----

А оно мне надо?


В посте первом

-------

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

Задача формлируется так:

- у Пети - одно яблоко

- у Маши - две груши


Требуется: реши!

#8 
Срыв покровов патриот24.02.24 09:38
NEW 24.02.24 09:38 
в ответ Fleitist 23.02.24 20:19

ну вот так например

class Program {

static object lockObj = new object();


static void FunctionCDE() {

lock (lockObj) {

Thread.Sleep(2000); // Имитация работы функции

}
}
}

#9 
AlexNek патриот24.02.24 11:27
AlexNek
NEW 24.02.24 11:27 
в ответ Fleitist 23.02.24 23:47

Мне вот только интересно какая была цель вашего поста?


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


#10 
alex445 коренной житель24.02.24 12:01
NEW 24.02.24 12:01 
в ответ Fleitist 23.02.24 20:19

Fleitist, так вы корову не продадите. Сначала ваш вариант, чтобы было видно ваши попытки. Можно попробовать ещё на Stackoverflow спросить, но там тоже иногда хотят видеть хотя бы какие-то первоначальные поползновения.

#11 
alex445 коренной житель24.02.24 12:07
NEW 24.02.24 12:07 
в ответ Срыв покровов 24.02.24 09:38, Последний раз изменено 24.02.24 12:09 (alex445)

Что лучше - использовать пачку объектов синхронизации (для каждого потока), применяемых последовательно (lock(A) lock (B) ...) или просто фильтровать потоки по тем же их именам на одном объекте синхронизации?

#12 
Срыв покровов патриот24.02.24 13:46
NEW 24.02.24 13:46 
в ответ alex445 24.02.24 12:07, Последний раз изменено 24.02.24 13:48 (Срыв покровов)

хм. Я кажется условия задачи неправильно понял: А и С тоже не должны работать параллельно, так ведь?

Даже интересно стало))

#13 
Murr патриот24.02.24 14:24
Murr
NEW 24.02.24 14:24 
в ответ Срыв покровов 24.02.24 09:38

насколько Я понял ему надо продолжать А и Б в параллели.

Так что видится какой-то враппер-менеджер...

#14 
NightWatch коренной житель24.02.24 19:37
NightWatch
NEW 24.02.24 19:37 
в ответ Fleitist 23.02.24 20:19

Что-то типа этого?

public class MyClass
{
  private readonly Synchronization sync = new Synchronization();

  public void MethodA()
  {
    sync.EnterParallel();
    try {
      // body
    } finally {
      sync.ExitParallel();
    }
  }

  public void MethodB()
  {
    sync.EnterParallel();
    try {
      // body
    } finally {
      sync.ExitParallel();
    }
  }

  public void MethodC()
  {
    sync.Enter();
    try {
      // body
    } finally {
      sync.Exit();
    }
  }

  public void MethodD()
  {
    sync.Enter();
    try {
      // body
    } finally {
      sync.Exit();
    }
  }

  public void MethodE()
  {
    sync.Enter();
    try {
      // body
    } finally {
      sync.Exit();
    }
  }

  private class Synchronization
  {
    private readonly object syncRoot = new object();
    private readonly object counterSync = new object();
    private int counter = 0;

    public void Enter()
    {
      Monitor.Enter(syncRoot);
    }

    public void EnterParallel()
    {
      lock (counterSync) { 
        if (counter < 1) {
          Monitor.Enter(syncRoot);
        }
        counter++;
      }
    }

    public void Exit()
    {
      Monitor.Exit(syncRoot);
    }

    public void ExitParallel()
    {
      lock (counterSync) {
        counter--;
        if (counter < 1) {
          Monitor.Exit(syncRoot);
        }
      }
    }
  }
}
#15 
Fleitist прохожий24.02.24 20:06
NEW 24.02.24 20:06 
в ответ NightWatch 24.02.24 19:37

А что если обобщить немного? Если не толко AB параллельны, но и пара CD к примеру? Общее решение будет выглядеть проще и элегантнее. Но на первый пункт браво. Очень близко.

#16 
alex445 коренной житель24.02.24 21:54
NEW 24.02.24 21:54 
в ответ NightWatch 24.02.24 19:37
Что-то типа этого?

У вас какой-то кастомный Semaphore. Надо только добавить фильтр по потокам, пришедшим с методов, которые не могут быть запущены в параллели.

#17 
alex445 коренной житель24.02.24 21:56
NEW 24.02.24 21:56 
в ответ Murr 24.02.24 14:24
Так что видится какой-то враппер-менеджер...

Берём код Семафора, и подгоняем под себя. ))

#18 
Fleitist прохожий24.02.24 23:02
NEW 24.02.24 23:02 
в ответ alex445 24.02.24 21:56

Одного семафора не будет достаточно.

#19 
MrSanders коренной житель25.02.24 10:44
NEW 25.02.24 10:44 
в ответ Fleitist 24.02.24 23:02

А каждый метод из этих "свободных" пар, можно исполнять параллельно? Т.е. АА, BB или даже ААААААBBBBB? Или исключения только для групп методов: "все методы этой группы могут исполняться одновременно, но не больше 1 потока на каждый отдельный метод"?

#20 
1 2 все