Задачка на синхронизацию
1. Имеется некий класс, содержащий пять функций A, B, C, D, E. Первые две функции A и B могут работать параллельно. Все остальные комбинации функций должны быть синхронизованы, т.е. если выполняется C, то D блокируется и ожидает. Это касается также таких комбинаций, как-то АС, СА, AD, DA, AE, EA, BC, CB и т.п.
2. Задачу можно обобщить до любого количества параллелизуемых, а также их подмножеств. Синхронизируемые также не ограничены в росте.
Реальная задача из практики.
А в чём проблема то? все давно известно
https://csharp.webdelphi.ru/mnogopotochnost-v-c-sposoby-si...
https://microsin.net/programming/pc/threading-in-csharp-pa...
Не знаю в чем проблема. В реализации задачи согласно ее условиям?
В реализации задачи согласно ее условиям
ну так это ваша проблема решить задачу, а когда есть что никак не получается, тогда можно и спрашивать.
Для С шарпа все решения по ссылкам, для остальных подобных языков принципы аналогичны.
Для вашего случая добавляется просто еще одно условие синхронизации.
ну так это ваша проблема решить задачу
Так я ж не против, хотелось услышать другие мнения. Вы вот написали.
тогда можно и спрашивать
Спасибо, буду теперь знать, что можно и что нельзя.
теперь знать, что можно и что нельзя.
Не совсем верное толкование.
Спрашивайте, что угодно, только не на всё вопросы будет получен ожидаемый ответ.
В данном случае, решать учебную задачку за вас здесь никто не будет.
Но вам предстоит решить две проблемы
1. Определить текущее состояние класса и его соотношение с вызываемой функцией. Иначе говоря, решить - нужно использовать синхронизацию или нет.
2. Как синхронизировать вызов функции?
Попробуйте вначале шаг 2, когда любую функцию нужно синхронизировать.
Затем сделайте класс для шага 1, хотя возможно это будет сложно для вас, тогда делайте всё по месту.
Давайте попробуем пройтись по шагам. В посте первом условия задачи сформулированы в достаточной степени формально, без отвлечений на детали технических реализаций. Попробуйте прочесть. Когда осознаете поставленную задачу, попробуйте ее реализовать на любом доступном вам языке, например C# - без разницы. Вы вправе применять любые средства синхронизации, некоторые из которых вы любезно предоставили по вашим ссылкам. Когда вы доберетесь до проблем с реализацией (надеюсь) и еще раз перечитаете условия задачи, то вы можете тогда ответить. Осветите проблематику возможной реализации, не забыв при этом упомянуть неполноту по Гёделю перечисленных вами средств. Конечно же, не забудьте упомянуть оные в списке рекомендуемой литературы, как любезно предоставленные вами вышеизложенные(зачеркнуто) вышеприведенные ссылки. Думаю только и именно тогда, коллега, возникнет импульс к дискурсу, чего и пытался достигнуть ваш покорный слуга.
Когда осознаете поставленную задачу
-----
А оно мне надо?
В посте первом
-------
я тебе сошлюсь на содержание учебника по математике одной из великих держав где вновь купленные электрички катают старым советским дизельком.
Задача формлируется так:
- у Пети - одно яблоко
- у Маши - две груши
Требуется: реши!
ну вот так например
class Program
{
static object lockObj = new object();
static void FunctionCDE()
{
lock (lockObj) {
Thread.Sleep(2000); // Имитация работы функции
}
}
}
Мне вот только интересно какая была цель вашего поста?
Потому как стиль ответа не предполагает вариант, что человеку нужно какое то решение.
Fleitist, так вы корову не продадите. Сначала ваш вариант, чтобы было видно ваши попытки. Можно попробовать ещё на Stackoverflow спросить, но там тоже иногда хотят видеть хотя бы какие-то первоначальные поползновения.
Что лучше - использовать пачку объектов синхронизации (для каждого потока), применяемых последовательно (lock(A) lock (B) ...) или просто фильтровать потоки по тем же их именам на одном объекте синхронизации?
хм. Я кажется условия задачи неправильно понял: А и С тоже не должны работать параллельно, так ведь?
Даже интересно стало))
насколько Я понял ему надо продолжать А и Б в параллели.
Так что видится какой-то враппер-менеджер...
Что-то типа этого?
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); } } } } }
А что если обобщить немного? Если не толко AB параллельны, но и пара CD к примеру? Общее решение будет выглядеть проще и элегантнее. Но на первый пункт браво. Очень близко.
Что-то типа этого?
У вас какой-то кастомный Semaphore. Надо только добавить фильтр по потокам, пришедшим с методов, которые не могут быть запущены в параллели.
А каждый метод из этих "свободных" пар, можно исполнять параллельно? Т.е. АА, BB или даже ААААААBBBBB? Или исключения только для групп методов: "все методы этой группы могут исполняться одновременно, но не больше 1 потока на каждый отдельный метод"?