одновременный запуск метода синглтона
От: zuv  
Дата: 19.04.05 14:35
Оценка:
Что будет если разные потоки попытаются запустить одновременно один и тот же метод синглтона? хм а то тут пришло в голову, что поведение будет неизвестно.
... << RSDN@Home 1.1.4 beta 4 rev. 358>>
Re: одновременный запуск метода синглтона
От: LioLick  
Дата: 19.04.05 14:43
Оценка:
Здравствуйте, zuv, Вы писали:

zuv>Что будет если разные потоки попытаются запустить одновременно один и тот же метод синглтона? хм а то тут пришло в голову, что поведение будет неизвестно.


Что за синглтон?
Какая потоковая модель?
Какой апартамент?
GL!
Re[2]: одновременный запуск метода синглтона
От: zuv  
Дата: 19.04.05 14:50
Оценка:
Здравствуйте, LioLick, Вы писали:

LL>Что за синглтон?

мейерса
LL>Какая потоковая модель?
множество неконтролируемых процессом дочерних потоков
LL>Какой апартамент?
с этого места поподробнее?
... << RSDN@Home 1.1.4 beta 4 rev. 358>>
Re: одновременный запуск метода синглтона
От: GarryIV  
Дата: 19.04.05 14:51
Оценка:
Hello, zuv!

z> Что будет если разные потоки попытаются запустить одновременно один и

z> тот же метод синглтона? хм а то тут пришло в голову, что поведение будет
z> неизвестно.

Для того чтоб все было известно применяют различные объекты синхронизации — критические секции, мьютексы, семафоры etc.
Posted via RSDN NNTP Server 1.9
WBR, Igor Evgrafov
Re[2]: одновременный запуск метода синглтона
От: zuv  
Дата: 19.04.05 14:54
Оценка:
Здравствуйте, GarryIV, Вы писали:

GIV>Для того чтоб все было известно применяют различные объекты синхронизации — критические секции, мьютексы, семафоры etc.


хм но у меня происходит простая запись в лог файлы, соответственно переменные не меняются, кроме строк для записи. все работает, заинтересовало на предмет возникновения нештатных ситуаций
... << RSDN@Home 1.1.4 beta 4 rev. 358>>
Re[3]: одновременный запуск метода синглтона
От: LioLick  
Дата: 19.04.05 14:59
Оценка:
Здравствуйте, zuv, Вы писали:

zuv>Здравствуйте, LioLick, Вы писали:


LL>>Что за синглтон?

zuv>мейерса
LL>>Какая потоковая модель?
zuv>множество неконтролируемых процессом дочерних потоков
LL>>Какой апартамент?
zuv>с этого места поподробнее?

Пардон, я подумал это COM-объект

Вопрос в том какие методы вызываются из разных потоков и какими данными объекта они оперируют
GL!
Re[4]: одновременный запуск метода синглтона
От: zuv  
Дата: 19.04.05 15:02
Оценка:
Здравствуйте, LioLick, Вы писали:

LL>Вопрос в том какие методы вызываются из разных потоков и какими данными объекта они оперируют


я уже оисал в соседней ветке
... << RSDN@Home 1.1.4 beta 4 rev. 358>>
Re[3]: одновременный запуск метода синглтона
От: GarryIV  
Дата: 19.04.05 15:03
Оценка:
Hello, zuv!

GIV>> Для того чтоб все было известно применяют различные объекты

GIV>> синхронизации — критические секции, мьютексы, семафоры etc.

z> хм но у меня происходит простая запись в лог файлы, соответственно

z> переменные не меняются, кроме строк для записи. все работает,
z> заинтересовало на предмет возникновения нештатных ситуаций

Если несколько потоков пишут в один файл надо синхронизировать записть в файл. Для такого случая достаточно критической секции. Про какие нештатные ситуации ты говоришь я не очень понимаю... Можно а примере пояснить чего ты опасаешься?
Posted via RSDN NNTP Server 1.9
WBR, Igor Evgrafov
Re[4]: одновременный запуск метода синглтона
От: zuv  
Дата: 19.04.05 15:10
Оценка:
Здравствуйте, GarryIV, Вы писали:

GIV>Если несколько потоков пишут в один файл надо синхронизировать записть в файл. Для такого случая достаточно критической секции. Про какие нештатные ситуации ты говоришь я не очень понимаю... Можно а примере пояснить чего ты опасаешься?


я пишу через поток вывода информацию в файл для этого создал отдельный класс, соответственно метод класса получает строку с записью, добавляет служебную иинформацию из класса, открывает файл через ofstream и производит запись в файл. насколько мне изветсно, поскольку все работает под линукс строка через поток записывается целиком файл, значит нужды синхронизации файла не возникает. меня интересует поведение программы когда уже работающий метод запускается во второй раз. пескольку запись происходит в только что созданные переменные их тоже синхронизировать как мне кажется не нужно. просто плохо знаю поведение и опасаюсь что вылезет через некоторое вермя какая-то гадость
... << RSDN@Home 1.1.4 beta 4 rev. 358>>
Re: одновременный запуск метода синглтона
От: bkat  
Дата: 19.04.05 15:15
Оценка:
Здравствуйте, zuv, Вы писали:

zuv>Что будет если разные потоки попытаются запустить одновременно один и тот же метод синглтона? хм а то тут пришло в голову, что поведение будет неизвестно.


У синглтона нету никакой особой специфики в этом случае по сравлению с обычными объектами.
Ну только что инициализация и уничтожение являются специфичными для него.
Так что применяй стандартные методы синхронизации доступа.
Re[3]: одновременный запуск метода синглтона
От: g_i  
Дата: 19.04.05 19:36
Оценка:
Здравствуйте, zuv, Вы писали:

zuv>Здравствуйте, GarryIV, Вы писали:


GIV>>Для того чтоб все было известно применяют различные объекты синхронизации — критические секции, мьютексы, семафоры etc.


zuv>хм но у меня происходит простая запись в лог файлы, соответственно переменные не меняются, кроме строк для записи. все работает, заинтересовало на предмет возникновения нештатных ситуаций


Thread Safety in the Standard C++ Library
See Also iostream Programming
When /MT, /MTd, /MD, or /MDd is used, the following thread-safety rules are in effect:
....
iostream Classes
Note that reading from a stream buffer is not considered to be a read operation. It should be considered as a write operation, because this changes the state of the class.

For reads to the same object, the object is thread safe for reading:
From one thread at a time when no writers on other threads.
From many threads at a time when no writers on other threads.

For writes to the same object, the object is thread safe for writing:
From one thread when no readers on other threads.
From many threads (when accesses are limited to stream buffers).

For reads to different objects of the same class, the object is thread safe for reading:
From one thread at a time.
From one thread at a time when no writers on other threads.
From many threads at a time.
From many threads at a time when no writers on other threads.

For writes to different objects of the same class, the object is thread safe for writing:
From one thread when no readers on other threads
From many threads
Re: одновременный запуск метода синглтона
От: Аноним  
Дата: 20.04.05 01:44
Оценка:
Здравствуйте, zuv, Вы писали:

zuv>Что будет если разные потоки попытаются запустить одновременно один и тот же метод синглтона? хм а то тут пришло в голову, что поведение будет неизвестно.


да тоже самое будет, что для обычного объекта. сломается подло как-нибудь, если метод сам по себе требует синхронизации.

единственное исключение — это статический метод instance. тут существует два подхода

1. для этого метода завести свой личный мьютекс или критическую секцию, а это означает, что нужно будет создать такой объект статически — а это зло.

2. перед тем, как запускать потоки, резко позвать все instance всех сингтонов, тогда они создадутся поочередно в одном потоке и не надо мучиться со статическими мьютексами.

ну а самый лучший способ, вообще синглтоны не использовать! надо помнить, что синглтон, это глобальная переменная в овечьей шкуре и названная умным словом
Re[2]: одновременный запуск метода синглтона
От: Mr.Chipset Россия http://merlinko.com
Дата: 20.04.05 01:57
Оценка:
Здравствуйте, Аноним, Вы писали:

А>ну а самый лучший способ, вообще синглтоны не использовать! надо помнить, что синглтон, это глобальная переменная в овечьей шкуре и названная умным словом


Позволю себе не согласиться, будет хорошо если вы меня переубедите.
Глобальная переменная предназначена для несколько других целей, в частности — обмена информацией, ну и может, синхронизации нескольких функций. В любой момент может быть создана новая переменная оного типа.
Синглетона суть в создании обьекта, дублирование которого является бесмысленным действом — кейбоарда, мышь, лог, принтсервер и прочие...
Менеджер виртуальной памяти Windows же, не клеймят словом "глобальная переменная" и не забрасывают помидорами, яблоками и прочими порождениями огородно-пищевой промышленности?
Всё есть моё ИМХО.
"Всё что не убивает нас, делает нас сильнее..."
Re[3]: одновременный запуск метода синглтона
От: Аноним  
Дата: 20.04.05 02:21
Оценка:
Здравствуйте, Mr.Chipset, Вы писали:

MC>Здравствуйте, Аноним, Вы писали:


А>>ну а самый лучший способ, вообще синглтоны не использовать! надо помнить, что синглтон, это глобальная переменная в овечьей шкуре и названная умным словом


MC>Позволю себе не согласиться, будет хорошо если вы меня переубедите.

MC>Глобальная переменная предназначена для несколько других целей, в частности — обмена информацией, ну и может, синхронизации нескольких функций. В любой момент может быть создана новая переменная оного типа.

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

MC>Синглетона суть в создании обьекта, дублирование которого является бесмысленным действом — кейбоарда, мышь, лог, принтсервер и прочие...


это его преимущество. недостаток — это точка входа instance(). она видна из каждого угла и все что использует этот синглтон должно видеть это instance()

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

на самом деле, есть пара паттернов, которые оставляя преимущества синглтона, убирают статический метод instance(), ну или по крайней мере локализуют его.

в частности, MonoState — http://c2.com/cgi/wiki?MonostatePattern

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

если это что-нибудь страшное, вроде Database Connection (а бывает и такое), то тестироваться становится существенно сложнее.

еще момент — кто убивает синглтон? в каком порядке они умрут? сумеют-ли они чисто освободить все захваченные ресурсы (и не только память)

вообще синглтоны — это практически религиозный вопрос, так что я особо настаивать не буду
Re: одновременный запуск метода синглтона
От: Mr.Chipset Россия http://merlinko.com
Дата: 20.04.05 02:29
Оценка:
Здравствуйте, zuv, Вы писали:

zuv>Что будет если разные потоки попытаются запустить одновременно один и тот же метод синглтона? хм а то тут пришло в голову, что поведение будет неизвестно.


Позволю себе процитировать Джонсона М. Харта, книгу Системное программирование в среде Win32, советы как избежать неправильного кода из главы про потоки:

Никогда не предсказывайте результат состязания потоков. В области планирования потоков может произойти все что угодно. Ваша программа должна предполагать, что любой готовый поток может начать работу в любой момент и что любой выполняемый поток может быть прерван также в любой момент.
"Среди потоков не существует никакого порядка, если только вы не зададите его" Бутенхоф.

Поэтому смело используйте мьютексы, крит. секции и прочее и не пытайтесь предсказать.
"Всё что не убивает нас, делает нас сильнее..."
Re[2]: одновременный запуск метода синглтона
От: zuv  
Дата: 20.04.05 07:04
Оценка:
Здравствуйте, Mr.Chipset, Вы писали:

MC>Поэтому смело используйте мьютексы, крит. секции и прочее и не пытайтесь предсказать.


блокировать лучше перед вызовом метода или можно в первом поле метода?
... << RSDN@Home 1.1.4 beta 4 rev. 358>>
Re: одновременный запуск метода синглтона
От: Pavel Chikulaev Россия  
Дата: 21.04.05 07:29
Оценка:
Маленький отрывок из книжки Александреску Modern C++ Design:

6.9 Living in a Multithreaded World

Singleton has to deal with threads, too. Suppose we have an application that has
just started, and two threads access the following Singleton:
Singleton& Singleton::Instance()
{
if (!pInstance_) // 1
{
pInstance_ = new Singleton; // 2
}
return *pInstance_; // 3
}

The first thread enters Instance and tests the if condition. Because it's the
very first access, pInstance_ is null, and the thread reaches the line marked //
2 and is ready to invoke the new operator. It might just happen that the OS
scheduler unwittingly interrupts the first thread at this point and passes
control to the other thread.
The second thread enters the stage, invokes Singleton::Instance(), and finds a
null pInstance_ as well because the first thread hasn't yet had a chance to
modify it. So far, the first thread has managed only to test pInstance_. Now say
the second thread manages to call the new operator, assigns pInstance_ in peace,
and gets away with it.
Unfortunately, as the first thread becomes conscious again, it remembers it was
just about to execute line 2, so it reassigns pInstance_ and gets away with it,
too. When the dust settles, there are two Singleton objects instead of one, and
one of them will leak for sure. Each thread holds a distinct instance of
Singleton, and the application is surely slipping toward chaos. And that's only
one possible situation—what if multiple threads scramble to access the
singleton? (Imagine yourself debugging this.)
Experienced multithreaded programmers will recognize a classic race condition
here. It is to be expected that the Singleton design pattern meets threads. A
singleton object is a shared global resource, and all shared global resources
are always suspect for race conditions and threading issues.
6.9.1 The Double-Checked Locking Pattern
A thorough discussion of multithreaded singletons was first presented by Douglas
Schmidt (1996). The same article describes a very nifty solution, called the
Double-Checked Locking pattern, devised by Doug Schmidt and Tim Harrison.
The obvious solution works but is not appealing:
Singleton& Singleton::Instance()
{
// mutex_ is a mutex object
// Lock manages the mutex
Lock guard(mutex_);
if (!pInstance_)
{
pInstance_ = new Singleton;
}
return *pInstance_;
}

Class Lock is a classic mutex handler (refer to the appendix for details on
mutexes). Lock's constructor locks the mutex, and its destructor unlocks the
mutex. While mutex_ is locked, other threads that try to lock the same mutex are
waiting.
We got rid of the race condition: While a thread assigns to pInstance_, all
others stop in guard's constructor. When another thread locks the lock, it will
find pInstance_ already initialized, and everything works smoothly.
However, a correct solution is not always an appealing one. The inconvenience is
its lack of efficiency. Each call to Instance incurs locking and unlocking the
synchronization object, although the race condition occurs only, so to say, once
in a lifetime. These operations are usually very costly, much more costly than
the simple if (!pInstance_) test. (On today's systems, the times taken by a
test-and-branch and a critical-section lock differ typically by a couple of
orders of magnitude.)
A would-be solution that attempts to avoid the overhead is presented in the
following code:
Singleton& Singleton::Instance()
{
if (!pInstance_)
{
Lock guard(mutex_);
pInstance_ = new Singleton;
}
return *pInstance_;
}

Now the overhead is gone, but the race condition is back. The first thread
passes the if test, but just when it is about to enter the synchronized portion
of code, the OS scheduler interrupts it and passes control to the other thread.
The second thread passes the if test itself (and to no one's surprise, finds a
null pointer), enters the synchronized portion, and completes it. When the first
thread is reactivated, it also enters the synchronized portion, but it's just
too late—again, two Singleton objects are constructed.
This seems like one of those brainteasers with no solution, but in fact there is
a very simple and elegant one. It's called the Double-Checked Locking pattern.
The idea is simple: Check the condition, enter the synchronized code, and then
check the condition again. By this time, rien ne va plus—the pointer is either
initialized or null all right. The code that will help you to understand and
savor the Double-Checked pattern follows. Indeed, there is beauty in computer
engineering.
Singleton& Singleton::Instance()
{
if (!pInstance_) // 1
{ // 2
Guard myGuard(lock_); // 3
if (!pInstance_) // 4
{
pInstance_ = new Singleton;
}
}
return *pInstance_;
}

Assume the flow of execution of a thread enters the twilight zone (commented
line 2). Here several threads may enter at once. However, in the synchronized
section only one thread makes it at a time. On line 3, there's no twilight
anymore. All is clear: The pointer has been either fully initialized or not at
all. The first thread that enters initializes the variable, and all others fail
the test on line 4 and do not create anything.
The first test is quick and coarse. If the Singleton object is available, you
get it. If not, further investigation is necessary. The second test is slow and
accurate: It tells whether Singleton was indeed initialized or the thread is
responsible for initializing it. This is the Double-Checked Locking pattern. Now
we have the best of both worlds: Most of the time the access to the singleton is
as fast as it gets. During construction, however, no race conditions occur.
Awesome. But . . .
Very experienced multithreaded programmers know that even the Double-Checked
Locking pattern, although correct on paper, is not always correct in practice.
In certain symmetric multiprocessor environments (the ones featuring the
so-called relaxed memory model), the writes are committed to the main memory in
bursts, rather than one by one. The bursts occur in increasing order of
addresses, not in chronological order. Due to this rearranging of writes, the
memory as seen by one processor at a time might look as if the operations are
not performed in the correct order by another processor. Concretely, the
assignment to pInstance_ performed by a processor might occur before the
Singleton object has been fully initialized! Thus, sadly, the Double-Checked
Locking pattern is known to be defective for such systems.
In conclusion, you should check your compiler documentation before implementing
the Double-Checked Locking pattern. (This makes it the Triple-Checked Locking
pattern.) Usually the platform offers alternative, nonportable
concurrency-solving primitives, such as memory barriers, which ensure ordered
access to memory. At least, put a volatile qualifier next to pInstance_. A
reasonable compiler should generate correct, nonspeculative code around volatile
objects.

--
Pavel Chikulaev
Posted via RSDN NNTP Server 1.9
Re: одновременный запуск метода синглтона
От: zuv  
Дата: 25.04.05 05:45
Оценка:
Всем большое спасибо за ответы.
... << RSDN@Home 1.1.4 beta 4 rev. 358>>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.