![]() |
Модераторы: Daevaorn |
![]() ![]() ![]() |
|
azesmcar |
|
|||
![]() uploading... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 6291 Регистрация: 12.11.2004 Где: Армения Репутация: 81 Всего: 211 |
Добрый день,
Есть класс SomeThread который делает конкретную задачу..обьектов этого класса - несколько. Каждый обьект имеет свое сойденение с базой данных и в принципе абсолютно изолирован (т.е. никаких глобальных данных и тому подобного, каждый обьект оперирует со своими локальными данными). Но как понимаете весь функционал не написан в модуле SomeThread, а он использует некие вспомогательные классы SystemUser, UserActionHandler и тому подобное. Вопрос в том что в каждом модуле мне нужно подключение к базе данных которое создано в классе SomeThread, а передавать его в каждый модуль, как-то некрасиво. Можно конечно создать синглтон, но..это потоки, т.е. на каждый поток должно быть свое подключение. Как это можно сделать? Было бы красиво что-то вроде
но вот как это реализовать? |
|||
|
||||
Lazin |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 41 Всего: 154 |
например, с помощью boost::call_once
|
|||
|
||||
azesmcar |
|
|||
![]() uploading... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 6291 Регистрация: 12.11.2004 Где: Армения Репутация: 81 Всего: 211 |
а без буста? меня больше принцип реализации интересует |
|||
|
||||
jonie |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5613 Регистрация: 21.8.2005 Где: Владимир Репутация: 15 Всего: 118 |
если я правильно понял задачу, то на каждый поток у вас свое подключение.
почему нельзя сделать в том классе что вы привели static map<threadId, connectionPtr> connections и при каждом обращении из конкретного потока (его id мы всегда сможем узнать) в каждой функции либо брать кешированное соединение либо создавать, пихать в кеш и использовать ? замечания: 1) map это НЕ std::map ! т.к. последний не потокобезопасен (хотя можно доступ к нему сделать таковым) 2) кешировать соединение не очень хорошо (точнее очень нехорошо). могут быть проблемы. все зависит от задачи. 3) конечно нужна функции "отключится от объекта" -------------------- Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет... |
|||
|
||||
Cтpaнник |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 53 Регистрация: 12.10.2008 Где: Россия, Санкт-Пет ербург Репутация: нет Всего: нет |
Если дело происходит в Windows и кроссплатформенность кода не нужна, то имеет смысл посмотреть в сторону платформенно-специфичных средств (а именно, в Win это TLS).
Например, в MSVC++ есть конструкция __declspec(thread) <тип данных> <имя переменной>; - таким образом создается экземпляр переменной, специфичный для вызывающего потока. Это позволит разделить connectionPtr и за каждым потоком закрепить свой экземпляр оного. Если применить еще и идиому RTTI, то, возможно, удастся решить и проблемы с "зависшими" или незакрытыми соединениями.... |
|||
|
||||
Lazin |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 41 Всего: 154 |
я совсем не понял задачи, но предположу, что лучше совсем обойтись без синглтона, вместо этого, можно передавать объект-подключение, через параметр конструктора потока, это сделает реализацию более гибкой, к тому-же, упростит написание тестов...
Добавлено через 6 минут и 1 секунду только если ты не пишешь разделяемую библиотеку ![]() |
|||
|
||||
azesmcar |
|
||||||||
![]() uploading... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 6291 Регистрация: 12.11.2004 Где: Армения Репутация: 81 Всего: 211 |
Абсолютно верно.
так и думал сделать, но
если учесть что в этот мап значения добавляются всего один раз в начале одним потоком, а потом ТОЛЬКО читают из него методом find, могут ли быть проблемы..со вчерашнего дня об этом и думаю.
нет, мне скорее нужно под линукс..но код кроссплатформенный. |
||||||||
|
|||||||||
jonie |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5613 Регистрация: 21.8.2005 Где: Владимир Репутация: 15 Всего: 118 |
-------------------- Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет... |
|||
|
||||
azesmcar |
|
|||
![]() uploading... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 6291 Регистрация: 12.11.2004 Где: Армения Репутация: 81 Всего: 211 |
ну это понятно, но тут есть что-то что мне не нравится, фактически потоки, у которых свое сойденение к базе должны ждать, хоть и недолго, но все же ждать пока поиск закончится..не нравится мне это. Может стоит сменить архитектуру пока не поздно? Но другого ничего не приходит на ум. Не писать же все в одном модуле? Никто не сталкивался с подобным что ли? Синглтон очень нужная в нашей жизни штука, а многопоточное приложение в наше время не редкость.. |
|||
|
||||
azesmcar |
|
||||
![]() uploading... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 6291 Регистрация: 12.11.2004 Где: Армения Репутация: 81 Всего: 211 |
Все!!! управился, привожу решение кому интересно.
В виндоуз есть такая штука как TLS (Thread Local Storage). Вещь полезная и полностью решающая данную задачу. В никсах она добавлена как патч, но это было давно и в принципе на данный момент вы вряд ли найдете систему которая не поддерживает TLS.
вот и все..обявляем статические переменные как
и наслаждаемся Thread Scope Static переменными! Всем спасибо. |
||||
|
|||||
Lazin |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 41 Всего: 154 |
нельзя использовать в dll, если ты будет загружать dll динамически, то будут проблемы Добавлено через 7 минут и 7 секунд workaround
|
|||
|
||||
azesmcar |
|
|||
![]() uploading... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 6291 Регистрация: 12.11.2004 Где: Армения Репутация: 81 Всего: 211 |
я и не собираюсь, но спасибо за информацию, почитаю про это. |
|||
|
||||
0xDX |
|
|||
Новичок Профиль Группа: Участник Сообщений: 44 Регистрация: 6.2.2009 Репутация: нет Всего: нет |
Делай селектор,
А в селекторе возвращаемые объекты вычисляй по ID потока Что то вроде switch(IdThread) { case First: retunrn array_object[1]; case Second: retunrn array_object[1]; default: return 0; } Весь код я не писал, если надо то скажи. |
|||
|
||||
azesmcar |
|
|||
![]() uploading... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 6291 Регистрация: 12.11.2004 Где: Армения Репутация: 81 Всего: 211 |
0xDX
![]() 1. Количество потоков - динамическое, еслиб я точно знал их количество - я бы придумал решения и покрасивей..хотя бы с шаблонами. 2. Откуда ты возьмешь First и Second? Это не константные значения. ИД потока изменяется при каждом запуске программы. 3. Чем тебе не нравится мое решение? Думаешь свитч красивее? |
|||
|
||||
0xDX |
|
|||
Новичок Профиль Группа: Участник Сообщений: 44 Регистрация: 6.2.2009 Репутация: нет Всего: нет |
azesmcar на винд работать не будет.
Ассоциативный контейнер полечит. |
|||
|
||||
![]() ![]() ![]() |
Правила форума "С++:Общие вопросы" | |
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |