Ориентированное на многопотоковое исполнение использование участников одиночного элемента

Я обнаружил, что %matplotlib notebook работает лучше для меня, чем встроенный с ноутбуками Jupyter.

Обратите внимание, что вам, возможно, потребуется перезапустить ядро, если раньше вы использовали %matplotlib inline.

15
задан Anthony Mastrean 1 December 2009 в 13:54
поделиться

9 ответов

доступ через 'Экземпляр' к 'Переключателю ()' ориентированный на многопотоковое исполнение класс? Если да, какой предположения, правила, и т.д. Если не, почему и как я могу зафиксировать его?

нет, это не ориентировано на многопотоковое исполнение.

В основном, оба потока могут работать эти Toggle функция одновременно, таким образом, это могло произойти

    // thread 1 is running this code
    if(value == 0) 
    {
        value = 1; 
        // RIGHT NOW, thread 2 steps in.
        // It sees value as 1, so runs the other branch, and changes it to 0
        // This causes your method to return 0 even though you actually want 1
    }
    else if(value == 1) 
    { 
        value = 0; 
    }
    return value;

, необходимо действовать со следующим предположением.

, Если 2 потока работают, они могут и чередоваться и взаимодействовать друг с другом случайным образом в любой точке. Можно быть половиной пути посредством записи или чтения целого числа на 64 бита или плавания (на ЦП на 32 бита), и другой поток может вскочить и изменить его из нижней части Вы.

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

можно решить, какой и где заблокировать путем размышления о вещах как это:

Для данного блока кода, если бы значение something было изменено из нижней части меня, это имело бы значение? Если бы это было бы, то необходимо заблокировать это something на время кода, где это имело бы значение.

Рассмотрение Вашего примера снова

    // we read value here
    if(value == 0) 
    {
        value = 1; 
    }
    else if(value == 1) 
    { 
        value = 0; 
    }
    // and we return it here
    return value;

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

, Таким образом, Вы сделали бы это:

lock( value )
{
     if(value == 0) 
     ... // all your code here
     return value;
}

ОДНАКО

В.NET можно только заблокировать Ссылочные типы. Int32 является Типом Значения, таким образом, мы не можем заблокировать его.
Мы решаем это путем представления 'фиктивного' объекта и блокировки , что везде, где мы хотели бы заблокировать 'значение'.

Это - то, к чему обращается Ben Scheirman .

28
ответ дан 1 December 2019 в 00:41
поделиться

Исходная реализация не ориентирована на многопотоковое исполнение, как Ben указывает

А простой способ сделать, это ориентированный на многопотоковое исполнение должно представить оператор блокировки. Например, как это:

public class MyClass
{
    private Object thisLock = new Object();
    private static readonly MyClass instance = new MyClass();
    public static MyClass Instance
    {
        get { return instance; }
    }
    private Int32 value = 0;
    public Int32 Toggle()
    {
        lock(thisLock)
        {
            if(value == 0) 
            {
                value = 1; 
            }
            else if(value == 1) 
            { 
                value = 0; 
            }
            return value;
        }
    }
}
8
ответ дан 1 December 2019 в 00:41
поделиться

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

private static object _lockDummy = new object();


...

lock(_lockDummy)
{
   //do stuff
}
2
ответ дан 1 December 2019 в 00:41
поделиться

Я также добавил бы защищенного конструктора к MyClass, чтобы препятствовать тому, чтобы компилятор генерировал общедоступного конструктора по умолчанию.

1
ответ дан 1 December 2019 в 00:41
поделиться

я думал, что, если бы я вывожу шаблон "одиночка" и вынуждаю всех получить новый экземпляр класса, он упростил бы некоторые проблемы..., но это не мешает никому больше инициализировать статический объект того типа и раздать это... или от отделения нескольких потоков, всего доступа 'Переключатель ()' от того же экземпляра.

Бинго :-)

я получаю его теперь. Это - жесткий мир. Мне жаль, что я не осуществлял рефакторинг унаследованный код :(

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

1
ответ дан 1 December 2019 в 00:41
поделиться

, Именно это я думал. Но, я я ищу детали... 'Переключитесь ()', не статический метод, но это - член статического свойства (при использовании 'Экземпляра'). Это то, что делает это общими для потоками?

, Если Ваше приложение является многопоточным и можно предвидеть, что несколько распараллеливают, получит доступ к тому методу, который делает его общими для потоками. Поскольку Ваш класс является Singleton, Вы знаете, что другой поток получит доступ к ТОМУ ЖЕ объекту, так предостережется о потокобезопасности Ваших методов.

И как это относится к одиночным элементам в целом. Я должен был бы обратиться к этому в каждом методе на моем классе?

, Поскольку я сказал выше, потому что это - одиночный элемент, Вы знаете, что другой поток получит доступ к тому же объекту, возможно одновременно. Это не означает, что необходимо заставить каждый метод получить блокировку. Если Вы замечаете, что simultaneos вызов может привести к поврежденному состоянию класса, то необходимо применить метод, упомянутый @Thomas

2
ответ дан 1 December 2019 в 00:41
поделиться

я могу предположить, что шаблон "одиночка" подвергает мой в других отношениях прекрасный ориентированный на многопотоковое исполнение класс всем проблемам потока постоянных статических участников?

номер Ваш класс просто не ориентирован на многопотоковое исполнение. Одиночный элемент не имеет никакого отношения к нему.

(я получаю голову вокруг того, что члены экземпляра обратились к статическому объекту, вызывают проблемы многопоточности)

, Она не имеет отношения к этому также.

необходимо думать как это: для 2 (или больше) потоки действительно ли возможно в моей программе получить доступ к этой части данных одновременно?

то, что Вы получаете данные через одиночный элемент или статическую переменную, или передающий в объекте как параметр метода, не имеет значения. В конце дня это - все просто некоторые биты и байты в RAM Вашего ПК и всем, что имеет значение, видят ли несколько потоков те же биты.

2
ответ дан 1 December 2019 в 00:41
поделиться

Кавычка:

if(value == 0) { value = 1; }
if(value == 1) { value = 0; }
return value;

value всегда будет 0...

0
ответ дан 1 December 2019 в 00:41
поделиться

Ну, я на самом деле не знаю C#, что хорошо..., но я в порядке в Java, таким образом, я дам ответ для этого, и надо надеяться эти два достаточно подобны, что это будет полезно. В противном случае я приношу извинения.

ответ, нет, это не безопасно. Один поток мог назвать Переключатель () в то же время, что и другой, и это возможно, хотя вряд ли с этим кодом, это Thread1 мог установить value промежуточный времена, что Thread2 проверяет его и когда он устанавливает его.

Для фиксации просто сделайте Переключатель () synchronized. Это не блокируется ни на чем или называет что-либо, что могло бы породить другой поток, который мог назвать Переключатель (), таким образом, это - все, что необходимо сделать, сохраняют его.

0
ответ дан 1 December 2019 в 00:41
поделиться
Другие вопросы по тегам:

Похожие вопросы: