Re[13]: Подсчет ссылок в реализации std
От: leshikru  
Дата: 30.07.04 09:24
Оценка:
Здравствуйте, Шахтер, Вы писали:

---

Ш>О том и речь. Классический string из stl не вполне удачно спроектирован. Некоторые напористые люди успели его впаять в стандарт. Как результат -- пользоваться им нельзя. Абзац.


Что-то я не совсем понял, почему?
Используйте STLport std::rope, если нужна строка со счетчиком ссылок, делением на куски и всем таким.
И в стандарт ее обещали добавить.
А std::string так и проектировался, как чистая замена Сишных строк один-к-одному. В них нельзя нормально сделать char &ch = &s[1] без копирования.
Re[11]: Подсчет ссылок в реализации std:
От: e-Xecutor Россия  
Дата: 30.07.04 10:28
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Здравствуйте, e-Xecutor, Вы писали:


EX>>А всё, что делалось — из кучи потоков делался запрос, который возвращал _копию_

EX>>структуры, в которой были строки. Строка в структуру копировалась из некоего контейнера.
EX>>В определённый момент строка в контейнере оказывалась мёртвой.
EX>>Хотя она там в рантайме вообще не менялась, заполнялась на взлёте.

EX>>И, пардон, греть голову на тему detached copy каждый раз когда

EX>>_копия_ строки возвращается в разные потоки — спасибо, такой реализации строк мне не надо...

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

Дык в нашем случае ничего не модифицировалось!
Максимум c_str от неё вызывался.


К>Мы профилировали строки в жёстком режиме ("выжимали кисаньку") и выяснили, что большая часть времени и памяти тратится на выделение буфера. Поэтому разумно делать так: в составе объекта строки держать буфер размера 16-32 символа (оптимум определяется профилированием) и мелочёвку хранить в нём. Немного усложняется метод reserve() — нужно проверять, куда нацелен указатель на данные (в буфере или в куче), и если в буфере — то следить за габаритами.


То бишь примерно так, как в vc 7.x сделано

С такими строками одна проблема. Их нельзя использовать если их нужно много
Но для таких случаев грех спец. класс не написать
Re[12]: Подсчет ссылок в реализации std:
От: Аноним  
Дата: 30.07.04 11:13
Оценка: :)
Здравствуйте, e-Xecutor, Вы писали:

EX>Здравствуйте, Кодт, Вы писали:


Народ! поделитесь плз, какой редиска нашептал вам на ушко, что киее либо stl контейнеры можно передавать между потоками???
откуда вообще беруться такие бредовые идеи? нравится работать с std::string — замечательно...; нужно передать строку в другой поток — передавай указаль а уже в получающем потоке кидай указатель в string! и даже при таком вареанте нужна синхронизация: ты можеш удалить указатель до того, как он попадет в принимающий поток и скопируется его значение, так что же вообще говорить о контейнерах??? и никакие блокировки, вставленные внутрь контейнера вам никогда не помогут в многопоточной среде, про это надо забыть как про то что можно писать в штанишки!
Re[13]: Подсчет ссылок в реализации std:
От: Кодт Россия  
Дата: 30.07.04 11:47
Оценка: :)
Здравствуйте, Аноним, Вы писали:

А>Народ! поделитесь плз, какой редиска нашептал вам на ушко, что киее либо stl контейнеры можно передавать между потоками???

А>откуда вообще беруться такие бредовые идеи? нравится работать с std::string — замечательно...; нужно передать строку в другой поток — передавай указаль а уже в получающем потоке кидай указатель в string! и даже при таком вареанте нужна синхронизация: ты можеш удалить указатель до того, как он попадет в принимающий поток и скопируется его значение, так что же вообще говорить о контейнерах??? и никакие блокировки, вставленные внутрь контейнера вам никогда не помогут в многопоточной среде, про это надо забыть как про то что можно писать в штанишки!

(Сказка произносится тихим, сиплым, страшным голосом — в надежде, что собеседник таки написает в штанишки).

Ты или на молоке обжёгся и дуешь на воду, или где-то что-то глубоко недопонял.
Не говоря уже о фразе "можешь удалить указатель". Это как? delete new LPVOID (some_pointer_value) ?
Перекуём баги на фичи!
Re[14]: Подсчет ссылок в реализации std:
От: Аноним  
Дата: 30.07.04 12:29
Оценка:
Здравствуйте, Кодт, Вы писали:

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


А>>Народ! поделитесь плз, какой редиска нашептал вам на ушко, что киее либо stl контейнеры можно передавать между потоками???

А>>откуда вообще беруться такие бредовые идеи? нравится работать с std::string — замечательно...; нужно передать строку в другой поток — передавай указаль а уже в получающем потоке кидай указатель в string! и даже при таком вареанте нужна синхронизация: ты можеш удалить указатель до того, как он попадет в принимающий поток и скопируется его значение, так что же вообще говорить о контейнерах??? и никакие блокировки, вставленные внутрь контейнера вам никогда не помогут в многопоточной среде, про это надо забыть как про то что можно писать в штанишки!

К>(Сказка произносится тихим, сиплым, страшным голосом — в надежде, что собеседник таки написает в штанишки).


К>Ты или на молоке обжёгся и дуешь на воду, или где-то что-то глубоко недопонял.

К>Не говоря уже о фразе "можешь удалить указатель". Это как? delete new LPVOID (some_pointer_value) ?

а как ты что-то передаеш в другой поток?
1)some_type* ptype = new some_type;
2)неким образом post ptype to thread
3)delete ptype;
вот так вот и можно удалить
Re[15]: Подсчет ссылок в реализации std:
От: Кодт Россия  
Дата: 30.07.04 12:50
Оценка:
Здравствуйте, Аноним, Вы писали:

К>>Ты или на молоке обжёгся и дуешь на воду, или где-то что-то глубоко недопонял.

К>>Не говоря уже о фразе "можешь удалить указатель". Это как? delete new LPVOID (some_pointer_value) ?

А>а как ты что-то передаеш в другой поток?

А>1)some_type* ptype = new some_type;
А>2)неким образом post ptype to thread
А>3)delete ptype;
А>вот так вот и можно удалить

А вот нефиг так делать потому что.

Заводится контейнер, который содержит передаваемые данные. Например, очередь std::queue.
Любой доступ к контейнеру — синхронный.
Время жизни данных (и, соответственно, хранилище) — зависит от логики работы. Если поток-отправитель дожидается обработки потоком-приёмником — то можно и на стеке держать (и передавать указатель). Если не дожидается — то в разделяемой памяти (статическое хранилище либо куча), причём заниматься этим может сам контейнер — всё тот же std::queue.
Владение данными — соответственно, у отправителя либо у контейнера.
Перекуём баги на фичи!
Re[16]: Подсчет ссылок в реализации std:
От: Аноним  
Дата: 30.07.04 14:11
Оценка:
Здравствуйте, Кодт, Вы писали:

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


К>>>Ты или на молоке обжёгся и дуешь на воду, или где-то что-то глубоко недопонял.

К>>>Не говоря уже о фразе "можешь удалить указатель". Это как? delete new LPVOID (some_pointer_value) ?

А>>а как ты что-то передаеш в другой поток?

А>>1)some_type* ptype = new some_type;
А>>2)неким образом post ptype to thread
А>>3)delete ptype;
А>>вот так вот и можно удалить

К>А вот нефиг так делать потому что.


К>Заводится контейнер, который содержит передаваемые данные. Например, очередь std::queue.

К>Любой доступ к контейнеру — синхронный.
К>Время жизни данных (и, соответственно, хранилище) — зависит от логики работы. Если поток-отправитель дожидается обработки потоком-приёмником — то можно и на стеке держать (и передавать указатель). Если не дожидается — то в разделяемой памяти (статическое хранилище либо куча), причём заниматься этим может сам контейнер — всё тот же std::queue.
К>Владение данными — соответственно, у отправителя либо у контейнера.

"те же яйца — вид с боку" какая разница как ты передаеш данные в поток, важно что когда ты их туда получил у тебя есть экземпляр данных и в передающем потоке и в принимающем, соответственно всегда есть возможность изменения данных, когда другой поток этого и не ждет... вообщем то в этом же и проблемма с std::string, которую тут так сильно мусолили... т.е. тыбе в любом случае, если ты конечно хочеш их двух потоков работать с этими данными, нужно организовывать внешнюю синхронизацию, и в этом смысле std::string не отличается ни от чаго другого
Re[17]: Подсчет ссылок в реализации std:
От: Batiskaf Израиль http://www.mult.ru/
Дата: 30.07.04 18:19
Оценка:
Здравствуйте, Аноним, Вы писали:

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


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


К>>>>Ты или на молоке обжёгся и дуешь на воду, или где-то что-то глубоко недопонял.

К>>>>Не говоря уже о фразе "можешь удалить указатель". Это как? delete new LPVOID (some_pointer_value) ?

А>>>а как ты что-то передаеш в другой поток?

А>>>1)some_type* ptype = new some_type;
А>>>2)неким образом post ptype to thread
А>>>3)delete ptype;
А>>>вот так вот и можно удалить

К>>А вот нефиг так делать потому что.


К>>Заводится контейнер, который содержит передаваемые данные. Например, очередь std::queue.

К>>Любой доступ к контейнеру — синхронный.
К>>Время жизни данных (и, соответственно, хранилище) — зависит от логики работы. Если поток-отправитель дожидается обработки потоком-приёмником — то можно и на стеке держать (и передавать указатель). Если не дожидается — то в разделяемой памяти (статическое хранилище либо куча), причём заниматься этим может сам контейнер — всё тот же std::queue.
К>>Владение данными — соответственно, у отправителя либо у контейнера.

А>"те же яйца — вид с боку" какая разница как ты передаеш данные в поток, важно что когда ты их туда получил у тебя есть экземпляр данных и в передающем потоке и в принимающем, соответственно всегда есть возможность изменения данных, когда другой поток этого и не ждет... вообщем то в этом же и проблемма с std::string, которую тут так сильно мусолили... т.е. тыбе в любом случае, если ты конечно хочеш их двух потоков работать с этими данными, нужно организовывать внешнюю синхронизацию, и в этом смысле std::string не отличается ни от чаго другого


Секундочку, строки и контейнеры это совершенно разные вещи, то что у стринга есть итераторы еще не значит что строки эквивалентны традиционным спискам, у строк и стратегии владения памятью могут отличаться от контейнеров, я себе мало представляю имплементацию вектора с COW. Так что давайте не смешивать...
Что касается контейнеров и потоков, то они не потокобезопасны не только в STL, и не только в С++, вот например в яве списки облегченные, а через специальную насадку можно получить потокобезопасные контейнеры, если я не ошибаюсь в .Нет-е такой же подход.
Will I live tomorrow? Well I just can't say
But I know for sure — I don't live today.
Jimi Hendrix.
Re[18]: Подсчет ссылок в реализации std:
От: Шахтер Интернет  
Дата: 02.08.04 15:48
Оценка: 1 (1) +1
Здравствуйте, adontz, Вы писали:

A>Здравствуйте, Шахтер, Вы писали:


A>>>Делись!

Ш>>Знаешь, есть такое слово -- копирайт.

A>ОК. Функциональные требования можешь представить? Типа чего бы ты хотел от строкового класса, если бы реализовывал не сам.


Через неделю напишу. Когда домой приеду.
... << RSDN@Home 1.1.0 stable >>
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re[18]: Подсчет ссылок в реализации std:
От: Аноним  
Дата: 03.08.04 06:24
Оценка:
Здравствуйте, Batiskaf, Вы писали:

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


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


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


К>>>>>Ты или на молоке обжёгся и дуешь на воду, или где-то что-то глубоко недопонял.

К>>>>>Не говоря уже о фразе "можешь удалить указатель". Это как? delete new LPVOID (some_pointer_value) ?

А>>>>а как ты что-то передаеш в другой поток?

А>>>>1)some_type* ptype = new some_type;
А>>>>2)неким образом post ptype to thread
А>>>>3)delete ptype;
А>>>>вот так вот и можно удалить

К>>>А вот нефиг так делать потому что.


К>>>Заводится контейнер, который содержит передаваемые данные. Например, очередь std::queue.

К>>>Любой доступ к контейнеру — синхронный.
К>>>Время жизни данных (и, соответственно, хранилище) — зависит от логики работы. Если поток-отправитель дожидается обработки потоком-приёмником — то можно и на стеке держать (и передавать указатель). Если не дожидается — то в разделяемой памяти (статическое хранилище либо куча), причём заниматься этим может сам контейнер — всё тот же std::queue.
К>>>Владение данными — соответственно, у отправителя либо у контейнера.

А>>"те же яйца — вид с боку" какая разница как ты передаеш данные в поток, важно что когда ты их туда получил у тебя есть экземпляр данных и в передающем потоке и в принимающем, соответственно всегда есть возможность изменения данных, когда другой поток этого и не ждет... вообщем то в этом же и проблемма с std::string, которую тут так сильно мусолили... т.е. тыбе в любом случае, если ты конечно хочеш их двух потоков работать с этими данными, нужно организовывать внешнюю синхронизацию, и в этом смысле std::string не отличается ни от чаго другого


B>Секундочку, строки и контейнеры это совершенно разные вещи, то что у стринга есть итераторы еще не значит что строки эквивалентны традиционным спискам, у строк и стратегии владения памятью могут отличаться от контейнеров, я себе мало представляю имплементацию вектора с COW. Так что давайте не смешивать...

а можно уточнить, в чем разница между строками и контейнерами? только не надо привязываться к списку, контейнеров и других небольшая кучка
B>Что касается контейнеров и потоков, то они не потокобезопасны не только в STL, и не только в С++, вот например в яве списки облегченные, а через специальную насадку можно получить потокобезопасные контейнеры, если я не ошибаюсь в .Нет-е такой же подход.
так в том то и дело — любые данные, которые ты передаеш в поток, далжны быть защищены тобой... и невозможно никакими блокировками внутри структуры (контейнера) сделать стректуру потокобезопасной!
Re[13]: Подсчет ссылок в реализации std:
От: e-Xecutor Россия  
Дата: 03.08.04 06:32
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, e-Xecutor, Вы писали:


EX>>Здравствуйте, Кодт, Вы писали:


А>Народ! поделитесь плз, какой редиска нашептал вам на ушко, что киее либо stl контейнеры можно передавать между потоками???

//skipped

Тебя почитать, так вообще передавать данные между потоками нельзя

Еще раз:

class InfoProvider{
public:
  std::string getInfo(const std::string& key)const
  {
    MutexGuard g(mtx);
    StringToStringMap::iterator it=infoMap.find(key);
    if(it==infoMap.end())return "";
    return *it;
  }
protected:
  typedef std::map<std::string,std::string> StringToStringMap;
  StringToStringMap infoMap;
  Mutex mtx;
};


Что не так в этом коде?

Обращение к методу getInfo происходит из разных потоков.
Возвращается им (казалось бы) копия строки.
ИМХО реализация по умолчанию должна делать, что бы не казалось.
То бишь по умолчанию копирование должно делать именно копирование.

ИМХО, если хочется каких-то нетривиальных оптимизаций, их надо делать руками,
или пользовать конкретные классы, с конкретным поведением.
Re[19]: Подсчет ссылок в реализации std:
От: Batiskaf Израиль http://www.mult.ru/
Дата: 03.08.04 07:03
Оценка:
Здравствуйте, Аноним, Вы писали:


B>>Секундочку, строки и контейнеры это совершенно разные вещи, то что у стринга есть итераторы еще не значит что строки эквивалентны традиционным спискам, у строк и стратегии владения памятью могут отличаться от контейнеров, я себе мало представляю имплементацию вектора с COW. Так что давайте не смешивать...

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

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

B>>Что касается контейнеров и потоков, то они не потокобезопасны не только в STL, и не только в С++, вот например в яве списки облегченные, а через специальную насадку можно получить потокобезопасные контейнеры, если я не ошибаюсь в .Нет-е такой же подход.

А>так в том то и дело — любые данные, которые ты передаеш в поток, далжны быть защищены тобой... и невозможно никакими блокировками внутри структуры (контейнера) сделать стректуру потокобезопасной!

Никто никому ничего не должен, каждый решает это по своему усмотрению, вот в яве по-моему самое оптимальное решение, предоставить оптимальный список и защищенный, в случае со строками этот подход вполне допустим, иметь строку для минимальных модификаций с синхронизацией, и потоконезащищенный строковый конструктор с продвинутой функциональностью для модификаций.
Will I live tomorrow? Well I just can't say
But I know for sure — I don't live today.
Jimi Hendrix.
Re[14]: Подсчет ссылок в реализации std:
От: Аноним  
Дата: 03.08.04 07:14
Оценка:
Здравствуйте, e-Xecutor, Вы писали:

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


А>>Здравствуйте, e-Xecutor, Вы писали:


EX>>>Здравствуйте, Кодт, Вы писали:


А>>Народ! поделитесь плз, какой редиска нашептал вам на ушко, что киее либо stl контейнеры можно передавать между потоками???

EX>//skipped

EX>Тебя почитать, так вообще передавать данные между потоками нельзя


EX>Еще раз:


EX>
EX>class InfoProvider{
EX>public:
EX>  std::string getInfo(const std::string& key)const
EX>  {
EX>    MutexGuard g(mtx);
EX>    StringToStringMap::iterator it=infoMap.find(key);
EX>    if(it==infoMap.end())return "";
EX>    return *it;
EX>  }
EX>protected:
EX>  typedef std::map<std::string,std::string> StringToStringMap;
EX>  StringToStringMap infoMap;
EX>  Mutex mtx;
EX>};
EX>


EX>Что не так в этом коде?


EX>Обращение к методу getInfo происходит из разных потоков.

EX>Возвращается им (казалось бы) копия строки.
EX>ИМХО реализация по умолчанию должна делать, что бы не казалось.
EX>То бишь по умолчанию копирование должно делать именно копирование.

EX>ИМХО, если хочется каких-то нетривиальных оптимизаций, их надо делать руками,

EX>или пользовать конкретные классы, с конкретным поведением.
Вот твои последнее слова полность передают суть... std::string это конкретный класс, с конкретным поведением, и его поведение таково, что он реализуется посредствоим подсчета ссылок (какая нибудь конкретная реализация, что всегда описано в доке), и если уж очень нужно, то std::string всегда можно заставить скопировать строку, просто съэмитировав запись.
Re[20]: Подсчет ссылок в реализации std:
От: Аноним  
Дата: 03.08.04 07:24
Оценка:
Здравствуйте, Batiskaf, Вы писали:

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



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

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

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


Даже не только предпологалось, а поскольку накого не устраивала работа с char* и все писали свои классы строк комитет и решил что нужно сделать некий такой общий класс и включить его в стандарт.


B>Никто никому ничего не должен, каждый решает это по своему усмотрению, вот в яве по-моему самое оптимальное решение, предоставить оптимальный список и защищенный, в случае со строками этот подход вполне допустим, иметь строку для минимальных модификаций с синхронизацией, и потоконезащищенный строковый конструктор с продвинутой функциональностью для модификаций.
Re[15]: Подсчет ссылок в реализации std:
От: e-Xecutor Россия  
Дата: 03.08.04 08:58
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Вот твои последнее слова полность передают суть... std::string это конкретный класс, с конкретным поведением, и его поведение таково, что он реализуется посредствоим подсчета ссылок (какая нибудь конкретная реализация, что всегда описано в доке), и если уж очень нужно, то std::string всегда можно заставить скопировать строку, просто съэмитировав запись.


И? Это мне что-нибудь гарантирует? Ничего это не гарантирует.

std::string, это не конкретный класс.
конкретной может быть реализация конкретной библиотеки/компилятора.
В стандарте ничего не написано, что константный метод c_str() может менять внутреннее состояние объекта.
Ладно. Проехали. Я всё равно останусь при своём мнении.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.