Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 2009.05.17;
Скачать: [xml.tar.bz2];

Вниз

AnsiString и его изменение потокобезопасно?   Найти похожие ветки 

 
It's not me   (2009-03-10 19:10) [0]

Имеем процедуру у некоторого класса:

procedure TMy.AddOpenDev(NewDev: string);
begin
 FOpenDev := FOpenDev + NewDev + "|" ;
end;


также имеем:

type
 TCallbackOpen = procedure(NewDev: string) of object;


Если разным потокам давать TCallbackOpen в виде AddOpenDev, это будет являться потокобезопасным?

На практике вроде работает тестово, но потоки вещь такая... Кто знает точно?
А плодить крит. секцию для работы с одной строчкой лениво. так что хочется знать правду )


 
DVM ©   (2009-03-10 19:13) [1]


> AnsiString и его изменение потокобезопасно?

нет


 
Игорь Шевченко ©   (2009-03-10 19:22) [2]

Мало информации


 
Тимохов ©   (2009-03-10 19:25) [3]


> DVM ©   (10.03.09 19:13) [1]
> > AnsiString и его изменение потокобезопасно?
> нет


смотря как смотреть:
В смысле не будет Access Violation (т.к. строка не станет инвалидной - у них там все продумано в этом плане), но результат вообще говоря не известен :)

автор, юзай крит. секцию.


 
Сергей М. ©   (2009-03-10 20:35) [4]


> It"s not me


Вот тебе сейчас дашь инф-цию к размышлению, а ты опять тут гнусавить будешь)
Тебе не надоело, а ?


 
тест(забыл пароль)   (2009-03-11 07:26) [5]

It"s not me   (10.03.09 19:10)
Что за переменные ты используешь?
Область видимости у них какая?
Если взаимодействие потоков(нитей)?
Взаимодействие потоков(нитей) между собой как происходит?
Код полностью выложи тогда будет понятно про что речь, пока что код ни про что не говорит.


 
KSergey ©   (2009-03-11 08:42) [6]

> Игорь Шевченко ©   (10.03.09 19:22) [2]
> Мало информации

А что еще надо уточнить?


 
It's not me   (2009-03-11 09:55) [7]

Игорь Шевченко ©   (10.03.09 19:22) [2]
Мало информации


что именно не хватает?

тест(забыл пароль)   (11.03.09 7:26) [5]
Что за переменные ты используешь?


FOpenDev это приват член класса TMy. Класс TMy умрет позже, чем все потоки, которые могут использовать TCallbackOpen, естественно. Вопрос про то, что будет если два разных потока в одно время будут пытаться модифицировать переменную типа string показанным образом.

тест(забыл пароль)   (11.03.09 7:26) [5]
Если взаимодействие потоков(нитей)?


какая разница и что ты называешь взаимодействием потоков?

тест(забыл пароль)   (11.03.09 7:26) [5]
Код полностью выложи тогда


кода слишком много, чтобы выкладывать.


 
Дмитрий С   (2009-03-11 11:01) [8]

То что ты привел точно потоко-НЕ-безопастно. Причем тут даже AnsiString не причем, так даже с Integer-ом делать нельзя.


 
Игорь Шевченко ©   (2009-03-11 11:22) [9]


> что именно не хватает?


Кода


 
It's not me   (2009-03-11 11:55) [10]


> так даже с Integer-ом делать нельзя

с integer"ом нельзя, я знаю. Но почему отсюда следует, что так нельзя делать с AnsiString - не понимаю.


> Кода

ну вы не будете разбираться в килобайтах кодах. Смысл в том, что отдельные потоки пытаются открыть некие устройства (ну допустим, COM-порты для наглядности), как только это получается - вызывают свой TCallbackOpen. Соответственно, момент открытия - произвольный, а TCallbackOpen у них у всех задан в AddOpenDev одного и того же экземпляра класса TMy. Внутренней синхронизации там нету.

Собственно, непонятно для чего нужен код. Фишка в том, что ссылку на функцию AddOpenDev имеют разные потоки и могут дернуть ее в любой момент, вот и вся информация.


 
Игорь Шевченко ©   (2009-03-11 12:04) [11]

It"s not me   (11.03.09 11:55) [10]


> Смысл в том, что отдельные потоки пытаются открыть некие
> устройства (ну допустим, COM-порты для наглядности), как
> только это получается - вызывают свой TCallbackOpen. Соответственно,
>  момент открытия - произвольный, а TCallbackOpen у них у
> всех задан в AddOpenDev одного и того же экземпляра класса
> TMy


Насколько я тебя понял, несколько потоков могут модифицировать одно и тоже свойство FOpenDev одного экземпляра класса, причем, каждый своим значением ?
В таком случае это вообще неверная идеология и никакая потокобезопасность и даже критическая секция тебя не спасут.
FOpenDev в этом случае должен быть свойством экземпляра класса, реализующего поток.


 
Сергей М. ©   (2009-03-11 12:27) [12]


> могут дернуть ее в любой момент


Картина маслом - "Когда в товарищах согласья нет .." (С)(R) И.А.Крылов "Лебедь, рак и щука"

Тебе "лениво" КС заводить ? Заведи любой другой подходящий объект синхронизации.
И его тоже лениво ? Ну тогда закономерно будешь иметь "А воз и ныне там", причем разорванный в клочья)


 
oxffff ©   (2009-03-11 12:29) [13]


>  FOpenDev := FOpenDev + NewDev + "|" ;


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


Не хорошо давать свои субъективные оценки, тем более вслух и как всегда без разъяснения.
И тем более что они некорректны.
Могу еще пустой try except припомнить.

Теперь по делу:
Не о чем не говорит?
Это список через разделить всех открытых устройств.

To автор

FOpenDev := FOpenDev + NewDev + "|"

Проблема этой строчки в том, в момент FOpenDev + NewDev, FOpenDev может не существовать или быть в другом месте из-за работы другого потока.

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

Простой пример

1 поток. Получили ссылку
1 поток начали чтение
2.поток Грохнули ссылку
1 поток Продолжаем чтение, но недействительной сслыке


 
KSergey ©   (2009-03-11 12:32) [14]

> Игорь Шевченко ©   (11.03.09 12:04) [11]
> и даже критическая секция тебя не спасут.
> FOpenDev в этом случае должен быть свойством экземпляра класса, реализующего поток.

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


 
Игорь Шевченко ©   (2009-03-11 12:34) [15]

oxffff ©   (11.03.09 12:29) [13]


> Не хорошо давать свои субъективные оценки, тем более вслух
> и как всегда без разъяснения.


Давай свои, кто мешает ?


> Могу еще пустой try except припомнить.


Конечно можешь - я еще в той теме говорил, что ты сам можешь писать как угодно и что угодно, можешь даже проповедовать свой стиль написания на форуме, но оставь за другими право на их точку зрения.
Доступно ?


 
oxffff ©   (2009-03-11 12:36) [16]


> Игорь Шевченко ©   (11.03.09 12:34) [15]


Доступно.


 
clickmaker ©   (2009-03-11 12:54) [17]

> procedure TMy.AddOpenDev(NewDev: string);
> begin
> FOpenDev := FOpenDev + NewDev + "|" ;
> end;

тут задумался... а что происходит при закрытии девайса?


 
It's not me   (2009-03-11 12:56) [18]


> Насколько я тебя понял, несколько потоков могут модифицировать
> одно и тоже свойство FOpenDev одного экземпляра класса,
> причем, каждый своим значением ?


Игорь, перечитайте пример в первом посте!

Есть экземпляр класса TMy. Он стартует раньше всех "рабочих" потоков и умирает после завершения всех "рабочих" потоков. Каждый из рабочих потоков получает в виде TCallbackOpen ссылку на функцию:

procedure TMy.AddOpenDev(NewDev: string);
begin
FOpenDev := FOpenDev + NewDev + "|" ;
end;

этого экземпляра класса.

Ну примитивно все выглядит так - стартуют потоки, они знают указатель на функцию, которую нужно дернуть, когда у них получится сделать нечто. Это ссылка на метод одного экземпляра класса TMy. Соответственно .как только потоком удается выполнить это нечто, они дергают этот метод. Сама реализация метода представлена.

Вопрос только в том, есть ли в ansistring встроенная синхронизация или нет. Я слышал, что там хитро все устроено, но не знаю насколько хитро. Видимо, синхронизациии нету... Придется одна эту строчку по контектации строки (или как это правильно называется :) ) оборочивать в синхронизацию )


 
Игорь Шевченко ©   (2009-03-11 13:08) [19]

It"s not me   (11.03.09 12:56) [18]


> Игорь, перечитайте пример в первом посте!



> Имеем процедуру у некоторого класса:
>
> procedure TMy.AddOpenDev(NewDev: string);
> begin
>  FOpenDev := FOpenDev + NewDev + "|" ;
> end;
>
> также имеем:
>
> type
>  TCallbackOpen = procedure(NewDev: string) of object;
>
> Если разным потокам давать TCallbackOpen в виде AddOpenDev,
>  это будет являться потокобезопасным?


Вот первый пост целиком.


> Есть экземпляр класса TMy. Он стартует раньше всех "рабочих"
> потоков и умирает после завершения всех "рабочих" потоков.
>  Каждый из рабочих потоков получает в виде TCallbackOpen
> ссылку на функцию:


Это из первого поста не следует.

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


 
It's not me   (2009-03-11 13:12) [20]


> Ты пойми простую вещь - проблема или вопрос у тебя, а не
> у отвечающих, поэтому в твоих интересах написать как можно
> больше

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

Я осветил проблему настолько, насколько мне кажется нужно, чтобы при обладании знаниями о string суметь ответить на вопрос. Если данных не хватает - задавайте уточняющие вопросы, я освещу в данном направлении тему. Рассказать тему полностью - нет никакой возможности и никому это не будет интересно.


 
Игорь Шевченко ©   (2009-03-11 13:31) [21]

It"s not me   (11.03.09 13:12) [20]


> Я осветил проблему настолько, насколько мне кажется нужно,
>  чтобы при обладании знаниями о string суметь ответить на
> вопрос. Если данных не хватает - задавайте уточняющие вопросы


Почитай, плз
http://ln.com.ua/~openxs/articles/smart-questions-ru.html

Еще раз - проблема у тебя, и в твоих интересах снизить количество уточняющих вопросов.


 
KSergey ©   (2009-03-11 13:58) [22]

> Игорь Шевченко ©   (11.03.09 13:31) [21]
> Еще раз - проблема у тебя,

Т.е. по делу о том, что крит. секции не спасут сказать нечего?


 
Игорь Шевченко ©   (2009-03-11 14:15) [23]

KSergey ©   (11.03.09 13:58) [22]

Да мне б узнать это дело. Возможно я неправильно понял автора, когда писал пост [11], но иметь дело с хранителями главной военной тайны я не хочу. Пусть сами мучаются.


 
KSergey ©   (2009-03-11 14:19) [24]

В [11] было безапеляционное заявление "крит. секции не спасут", без уточнения при каких условиях. Вот не спасут и все. Вообще. Никогда.
Видимо это не правда все ж? Так ведь?


 
oxffff ©   (2009-03-11 14:21) [25]


> It"s not me   (11.03.09 13:12) [20]


Мне полностью понятен твой вопрос и я дал тебе полный ответ на него.
см. [13]. Со слов To автор.


 
KSergey ©   (2009-03-11 14:24) [26]

> clickmaker ©   (11.03.09 12:54) [17]
> тут задумался... а что происходит при закрытии девайса?

"Ни шагу назад, ни шагу на месте..."


 
Игорь Шевченко ©   (2009-03-11 14:25) [27]

KSergey ©   (11.03.09 14:19) [24]

А я вроде как написал, что возможно неправильно понял ? И в [11] было указано, как я понял, и, соответственно, при этом понимании таки да, не спасут.


 
test ©   (2009-03-11 14:32) [28]

Автор ветки выложи наконец пример испоьзования этого чудо метода, пока что твой случай это [13].


 
oxffff ©   (2009-03-11 14:47) [29]


> It"s not me   (11.03.09 13:12) [20]


Этот вроде внешне безобидный код,

procedure DoBuggyCode(const Source:string;var Dest:string);
begin
Dest:=Source[1]+Source[2];    
///////////
//Еще что-то
///////////
Dest:=Source[1]+Source[2];
end;

можно превратить в потенциально опасный простым вызовом.
DoBuggyCode(a,a);


 
Skyle ©   (2009-03-11 14:54) [30]


> clickmaker ©   (11.03.09 12:54) [17]
> > procedure TMy.AddOpenDev(NewDev: string);
> > begin
> > FOpenDev := FOpenDev + NewDev + "|" ;
> > end;
>
> тут задумался... а что происходит при закрытии девайса?

А что тут думать...

procedure TMy.RemClosedDev(ClosedDev : String);
begin
 FOpenDev := StringReplace(FOpenDev, ClosedDev + "|", "", []);
end;


 
It's not me   (2009-03-11 15:28) [31]


> см. [13].

oxffff, я просто по посту [13] понял, что ты сам не очень точно знаешь, неуверенно отписао в стиле "может". Я сам понимаю, что в общем это МОЖЕТ привести к конфликтам. Но как конкретно устроены функции по работе со string не знаю.

Ты отписал, что:

>Проблема этой строчки в том, в момент FOpenDev + NewDev, FOpenDev
>может не существовать или быть в другом месте из-за работы другого
>потока


то есть, получим AV. Хотя постом выше Тимохов уверенно сказал:

>В смысле не будет Access Violation (т.к. строка не станет инвалидной - у
>них там все продумано в этом плане


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


 
test ©   (2009-03-11 15:39) [32]

It"s not me   (11.03.09 15:28) [31]
Если получишь AV это даже хорошо, но ты можеш получить взаимоисключающие команды, с ними ты делать что будешь?


 
oxffff ©   (2009-03-11 15:55) [33]


> It"s not me   (11.03.09 15:28) [31]


> из чего я сделал вывод, что ты до конца сам тонкостей реализации
> string"а не знаешь.


Поясни, как можно сделать такой вывод?

P.S.
Я тебе написал конкретный пример в [13] и [29].
Отсутствие AV не означает, что код корректный.


 
KSergey ©   (2009-03-11 15:59) [34]

> Игорь Шевченко ©   (11.03.09 14:25) [27]
> И в [11] было указано, как я понял,

> Игорь Шевченко ©   (11.03.09 12:04) [11]
> Насколько я тебя понял, несколько потоков могут модифицировать
> одно и тоже свойство FOpenDev одного экземпляра класса, причем, каждый своим значением ?

В такой постановке был выдан диагноз "не спасет никогда". Я с ним не согласен.
Ели я правильно понял дальнейшее, категоричность утверждения связана с предположением, что экземпляр TMy может быть не создан до старта потоков, однако сказано этого не было, а потому категоричность и однозначность вызывает у меня недоумение.
Ну либо я чего-то недопонимаю именно в указанной постановке.


 
It's not me   (2009-03-11 16:07) [35]


> Поясни, как можно сделать такой вывод?


я пояснил вообще-то. Давай еще раз:

Ты в посте [13] описал ситуацию, которая должна на мой взгляд привести к AV. (а что еще будет, если по твоим словам строчка может находиться уже в другом месте, чем думает один из потоков, в таком случае AV очень вероятен).
При этом Тимохов очень уверенно отписался, что AV уж точно не будет, типа в string все это продумано. И не уточнил что именно продумано.

Отсюда я сделал вывод, что ты сам не до конца знаешь тонкости реалзиации string, если фактически предположил то, чего быть не может.


 
Игорь Шевченко ©   (2009-03-11 16:09) [36]


> В такой постановке был выдан диагноз "не спасет никогда".
>  Я с ним не согласен.


Нет, категоричность утверждения была вызвана тем, что неизвестен собственно момент модификации, причем даже начала и окончания модификации, и нет гарантии, что один поток выполнит модификацию целиком, прежде чем другой поток не начнет такую же модификацию, в это время начнется чтение и прочитается неизвестно что. Писать кучу критических секций для этого - а смысл ? Надо убеждаться, что никто не пишет, в тот момент, когда происходит чтение, и в тот момент, когда происходит запись. Так как писателей потенциально много, то механизм синхронизации здорово усложняется.


 
It's not me   (2009-03-11 16:10) [37]

То есть, с одной стороны:

>т.к. строка не станет инвалидной - у них там все продумано в этом плане

а с другой стороны твое:

>FOpenDev может не существовать или быть в другом месте

что на мой взгляд можно перевести как: "FOpenDev может стать инвалидной строкой".


 
KSergey ©   (2009-03-11 16:27) [38]

> Игорь Шевченко ©   (11.03.09 16:09) [36]

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

Ну а здесь в простейшем случае можно на все про все одну крит. секцию завести, и если не предполагается слишком интенсивного обращения - то вполне себе хорошее решение получится. (Если слишком интенсивно - тогад все потоки будут тупо стоять в очереди на этой крит. секции, это уже фигня получается, а не многопоточность)


 
Игорь Шевченко ©   (2009-03-11 16:33) [39]

KSergey ©   (11.03.09 16:27) [38]

В данном случае (в рамках моего понимания задачи, когда куча потоков открывает кучу устройств и список открытых устройств надо где-то иметь, а возможно, показывать) я бы использовал список TThreadList, и, соответственно, при открытии добавлял бы туда, при закрытии удалял, а при чтении, соответственно, читал бы, с блокировкой.


 
oxffff ©   (2009-03-11 16:35) [40]


> It"s not me   (11.03.09 16:07) [35]
>
> > Поясни, как можно сделать такой вывод?
>
>
> я пояснил вообще-то. Давай еще раз:
>
> Ты в посте [13] описал ситуацию, которая должна на мой взгляд
> привести к AV. (а что еще будет, если по твоим словам строчка
> может находиться уже в другом месте, чем думает один из
> потоков, в таком случае AV очень вероятен).


А почему ты думаешь, что она приведет к AV?
Обращение по недействительному указателю может вызвать AV, а может и не вызвать. AV является реакцией ОС на исключения процессора, которые происходят при определенных условиях.
Например обращение к отсутствующей странице, выход за сегмент описываемый дескриптором.

В твоих словах есть сомнение должно быть или не должно быть AV.
Так ты уж определись кто ты -
It"s not me   (11.03.09 16:07) [35] или It"s not me   (11.03.09 15:28) [31].
Как тебе такой поворот событий?



Страницы: 1 2 3 вся ветка

Форум: "Прочее";
Текущий архив: 2009.05.17;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.58 MB
Время: 0.007 c
2-1238935538
random(1024)
2009-04-05 16:45
2009.05.17
Как из компонента TWebBrowser распечатать страничку...


2-1238769749
Кошкин
2009-04-03 18:42
2009.05.17
Как сделать проекцию на экран.


11-1200570250
Rocket
2008-01-17 14:44
2009.05.17
OpenDirDialog.InitialPath при UNICODE_CTRLS...


2-1238676821
f3nd3r
2009-04-02 16:53
2009.05.17
С++ DLL в Delphi


15-1236968185
Другг
2009-03-13 21:16
2009.05.17
Архивация и сжатие





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский