VladD2 wrote: > C>Только консервативный (т.е. мегахак). > А как ты вообще видишь себе прикручивание точного ЖЦ к языку > допускающему небезопасные операции с памятью и в котором отсуствуют > такие примитивы как массивы?
Как в C++/CLR, например. Который, кстати, остается единственным
нормальным языком, где сделана интероперабельность между GC и ручным
управлением памятью.
Здравствуйте, Cyberax, Вы писали:
C>Как в C++/CLR, например. Который, кстати, остается единственным C>нормальным языком, где сделана интероперабельность между GC и ручным C>управлением памятью.
Дык там тупо сделали два языка. Один С++, а другой не очень.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Andrei F., Вы писали:
AF>PS кстати, что меня удивляет в последнее время — это количество малолетних кулхацкеров, которые с восторгом пишут по форумам что-нибудь типа "оооо, С++ — это так круто, там все так сложно! C# и Java это вааще отстой, там все просто и проги никогда не валятся. А вот в C++ чуть что и сразу GPF, ууу, как круто" Видимо, таким вот будет новое поколение плюсовиков
меня точно так же удивляют преданные пользователи языков без автоматического полиморфизма, т-ех, где надо явно писать типы, нет лямбд и не поддерживается point-free programming style
Здравствуйте, Andrei F., Вы писали:
AF>Похоже, что сборки мусора и/или многопоточности в стандарте не будет, а сам стандарт будет выпущен в лучшем случае в 2009 году. Результат вполне закономерный, я не удивлен.
то что не будет GC- слава богу, иначеб сделали из языка- помойку.
А насчёт многопоточности- пофиг, буст он и в линуксе буст.
Здравствуйте, VladD2, Вы писали:
C>>Как в C++/CLR, например. Который, кстати, остается единственным C>>нормальным языком, где сделана интероперабельность между GC и ручным C>>управлением памятью. VD>Дык там тупо сделали два языка. Один С++, а другой не очень.
Ага. Но там хотя бы как-то продумали механизм их совмещения (чего не скажешь о D, например).
Здравствуйте, BulatZiganshin, Вы писали:
BZ>меня точно так же удивляют преданные пользователи языков без автоматического полиморфизма, т-ех, где надо явно писать типы, нет лямбд и не поддерживается point-free programming style
Здравствуйте, BulatZiganshin, Вы писали:
BZ>меня точно так же удивляют преданные пользователи языков без автоматического полиморфизма, т-ех, где надо явно писать типы, нет лямбд и не поддерживается point-free programming style
Другими словами тебя смущают Русские, Англечане и те кто пользуется SQL?
Мне даже трудно представить о чем идет речь. Видимо о Китайском.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Sni4ok, Вы писали:
S>то что не будет GC- слава богу, иначеб сделали из языка- помойку. S>А насчёт многопоточности- пофиг, буст он и в линуксе буст.
Ага. Что водка, что пулимет. Лиш бы с ног валило.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
WH>bManualReset WH>[in] Boolean that specifies whether a manual-reset or auto-reset event object is created. If TRUE, then you must use the ResetEvent function to manually reset the state to nonsignaled. If FALSE, the system automatically resets the state to nonsignaled after a single waiting thread has been released. WH>[/q]
WH>ИМХО выделеное с семафором не стыкуется.
Что именно не стыкуется? Классический семафор именно вручную и устанавливается, как иначе? Установка этого семафора — это сброс самого события. Этот автосброс можно сделать одной лишней строчкой кода-обёртки.
V>>т.е. если будет примитив-семафор, то все остальные делаются тонкой прослойкой в либе. WH>Теоритически да. Но приктически решение будет так себе.
Еще раз, все примитивы синхронизации делаются на семафорах, принципиально, а те, в свою очередь, на атомарных операциях инкремента/декремента. Например, открыты для доступа и изучения CRITICAL_SECTION в винде, полюбопытствуй. Мютекс (коим является и CriticalSection) — это структура из семафора и идентификатора треда/процесса. (Рекурсивный чуть сложнее, но не суть).
WH>Особенно если вспомнить про различные lock-free структуры данных.
Это к теме не относится, т.к. однофигственно применимо к любым примитивам синхронизации.
Здравствуйте, Cyberax, Вы писали:
VD>>Дык там тупо сделали два языка. Один С++, а другой не очень. C>Ага. Но там хотя бы как-то продумали механизм их совмещения (чего не скажешь о D, например).
Это да. Но Ди тут вроде как не обсуждался, а на то чтобы так радикально доработать язык Страуструп и комитет не пойдут. По крайне мере не пойдут на то чтобы тупо взять решение МС. А если они пойдут своим путем, то две шестнадцатиричные декады не хватит.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, vdimas, Вы писали:
V>Что именно не стыкуется? Классический семафор именно вручную и устанавливается, как иначе? Установка этого семафора — это сброс самого события. Этот автосброс можно сделать одной лишней строчкой кода-обёртки.
Учи матчасть.
Ибо под семафор может зайти только N=const потоков. Для того чтобы вошол новый старй должен выйти. Просто по определению.
А через этот примитив может пройти сколько угодно потоков.
Ну и где тут семафор?
V>Еще раз, все примитивы синхронизации делаются на семафорах, принципиально,
В теории любой примитив синхронизации можно выразить через любой другой примитив синхронизации.
Но на практике так никто не делает ибо тормозит.
А чтобы не тормозило каждый примитив синхронизации выпиливают под конкретную железку.
V>Это к теме не относится, т.к. однофигственно применимо к любым примитивам синхронизации.
Очень даже относится.
Ибо не смотря на теорию на практике все делать через семофоры это дурь полная ибо тормоза.
... << RSDN@Home 1.2.0 alpha rev. 745>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, WolfHound, Вы писали:
WH>Ибо под семафор может зайти только N=const потоков. Для того чтобы вошол новый старй должен выйти. Просто по определению. WH>А через этот примитив может пройти сколько угодно потоков. WH>Ну и где тут семафор?
Самому не стыдно? Потрать пять минут и пофантазируй. Намекну — ты всё правильно говоришь, именно, что кто-то должен "выйти", представь семафор объектом с методами enter(int timeout) и exit() и распиши событие на нём. Достаточно сделать допущение, что exit() выполняется из произвольного треда, что есть по факту, т.к. классический семафор — это структура, не запоминающая идентификаторы потоков.
V>>Еще раз, все примитивы синхронизации делаются на семафорах, принципиально, WH>В теории любой примитив синхронизации можно выразить через любой другой примитив синхронизации. WH>Но на практике так никто не делает ибо тормозит. WH>А чтобы не тормозило каждый примитив синхронизации выпиливают под конкретную железку.
Ну конкретно на 86-й железке делается через InterlockedIncrement/Decrement, т.е. через семафоры в совокупности с планировщиком в итоге. На дековской Alpha тоже, кстати.
V>>Это к теме не относится, т.к. однофигственно применимо к любым примитивам синхронизации. WH>Очень даже относится. WH>Ибо не смотря на теорию на практике все делать через семофоры это дурь полная ибо тормоза.
Ты там говорил об некоторых структурах, которые могут обходится без синхронизации вообще, так вот оно и было не по теме.
Здравствуйте, vdimas, Вы писали:
V>Самому не стыдно?
Мне нет.
А вот тебе должно быть.
Ибо если говорить о auto-reset event то это действительно семафор.
А вот manual-reset event ведет себя сильно иначе.
V>Потрать пять минут и пофантазируй.
Сам потрать.
V>Намекну — ты всё правильно говоришь, именно, что кто-то должен "выйти", представь семафор объектом с методами enter(int timeout) и exit() и распиши событие на нём. Достаточно сделать допущение, что exit() выполняется из произвольного треда, что есть по факту, т.к. классический семафор — это структура, не запоминающая идентификаторы потоков.
У классического семафора есть 3 операции:
1)init(int count)
2)enter — если лимит исчерпан ждет пока ктонибудь скажет exit
3)exit
У manual reset event 4 операции
1)init(bool state)
2)set — никогда не блокирует
3)reset — никогда не блокирует
4)wait — блокирует если состояние reset пропускает если состояние set
Ну и где тут семафор?
... << RSDN@Home 1.2.0 alpha rev. 745>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
V>>Самому не стыдно? WH>Мне нет. WH>А вот тебе должно быть. WH>Ибо если говорить о auto-reset event то это действительно семафор. WH>А вот manual-reset event ведет себя сильно иначе.
Точно сильно?
V>>Потрать пять минут и пофантазируй. WH>Сам потрать.
using System;
using System.Threading;
namespace SemaphoreProbe
{
// обёртка над виндовознымinternal class ClassicSemaphore
{
private Semaphore sem;
public ClassicSemaphore(int max) { sem = new Semaphore(max, max); }
public void Enter() { sem.WaitOne(); }
public void Exit() { sem.Release(); }
// Dispose() - лень
}
// целевой классinternal class Event {
private ClassicSemaphore sem = new ClassicSemaphore(1);
// семафор-наоборотpublic Event() { sem.Enter(); }
public virtual void Wait() { Reset(); Set(); }
public void Set() { sem.Exit(); }
public void Reset() { sem.Enter(); }
}
internal class AutoresetEvent : Event {
public override void Wait() { Reset(); }
}
// демонстрацияinternal class Program {
private static volatile Event ev1;
private static volatile bool finish = false;
private static void Main() {
Console.WriteLine("Autoreset Event Test:\n");
ev1 = new AutoresetEvent();
for (int i = 0; i < 10; i++)
new Thread(ThreadProcAutoreset).Start();
for (int i = 0; i < 10; i++) {
Thread.Sleep(1);
ev1.Set();
}
finish = true;
for (int i = 0; i < 10; i++)
ev1.Set();
finish = false;
Console.WriteLine("\nManual Reset Event Test:");
ev1 = new Event();
for (int i = 0; i < 10; i++)
new Thread(ThreadProcManual).Start();
for (int i = 0; i < 5; i++) {
Console.Write("\nSignaled: ");
ev1.Set();
Thread.Sleep(1);
ev1.Reset();
Console.WriteLine();
}
finish = true;
ev1.Set();
}
private static void ThreadProcAutoreset()
{
while (!finish) {
ev1.Wait();
if (!finish)
Console.WriteLine("Autoreset #" + Thread.CurrentThread.ManagedThreadId);
}
}
private static void ThreadProcManual()
{
while (!finish) {
ev1.Wait();
if (!finish)
Console.Write("#" + Thread.CurrentThread.ManagedThreadId + " ");
}
}
}
}
V>>Намекну — ты всё правильно говоришь, именно, что кто-то должен "выйти", представь семафор объектом с методами enter(int timeout) и exit() и распиши событие на нём. Достаточно сделать допущение, что exit() выполняется из произвольного треда, что есть по факту, т.к. классический семафор — это структура, не запоминающая идентификаторы потоков. WH>У классического семафора есть 3 операции: WH>1)init(int count) WH>2)enter — если лимит исчерпан ждет пока ктонибудь скажет exit WH>3)exit WH>У manual reset event 4 операции WH>1)init(bool state) WH>2)set — никогда не блокирует WH>3)reset — никогда не блокирует WH>4)wait — блокирует если состояние reset пропускает если состояние set WH>Ну и где тут семафор?
все вызовы event — блокирующие, просто в состоянии "signaled" блокировка сразу отпускается. Поэкспериментируй с затратами на WaitOne() виндового евента в сигнальном состоянии.
Здравствуйте, vdimas, Вы писали:
V>Я предвидел этот вопрос, потому и посоветовал поэкспериментировать с "родным" event и его WaitOne() в сигнальном состоянии.
И что там можно наэксперементировать?
Кстати запустил твой код на двуядерной машине.
Autoreset Event Test:
Autoreset #4
Autoreset #5
Autoreset #4
Autoreset #12
Autoreset #4
Autoreset #12
Autoreset #4
Autoreset #12
Autoreset #4
Unhandled Exception: System.Threading.SemaphoreFullException: Adding the given count to the semaphore would cause it to exceed its maximum count.
at System.Threading.Semaphore.Release(Int32 releaseCount)
at System.Threading.Semaphore.Release()
at SemaphoreProbe.ClassicSemaphore.Exit() in c:\work\ConsoleApplication5\Program.cs:line 13
at SemaphoreProbe.Event.Set() in c:\work\ConsoleApplication5\Program.cs:line 25
at SemaphoreProbe.Program.Main() in c:\work\ConsoleApplication5\Program.cs:line 56
чтд.
Эксперемены с несколькими Set'ами и Reset'ами привели к вылетам и зависаниям соответственно.
После переделки на настоящие Event'ы
internal class Event
{
private System.Threading.EventWaitHandle event_;
public Event()
{
event_ = Create();
}
protected virtual System.Threading.EventWaitHandle Create()
{
return new System.Threading.ManualResetEvent(true);
}
public virtual void Wait() { event_.WaitOne(); }
public void Set() { event_.Set(); }
public void Reset() { event_.Reset(); }
}
internal class AutoresetEvent : Event
{
protected override System.Threading.EventWaitHandle Create()
{
return new System.Threading.AutoResetEvent(true);
}
}
вылеты (в том числе с несколькими Set'ами и Reset'ами подряд) прекратились
однако начались зависания... что и не удивительно ибо см на ManagedThreadId'ы в твоем варианте.
после изменения кода
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, Andrei F., Вы писали:
AF>> а сам стандарт будет выпущен в лучшем случае в 2009 году. Результат вполне закономерный, я не удивлен.
VD>Наивняк ты, однако. VD>Этому стандарту не зра присвоили номер 0х. Это же шеснадцатиричный префикс, так что в него можно записать любую фиру от 0 до F. А при очень большом желании можно записать и две-три цифры. VD>Так что 9-ы год — это не очень реальная дата. Вот A-F — это более реальный срок. За одно можно преурочить выход нового стандарта к какому-нибудь юбилею. Например, к столетию Страутрупа.
Хотя бы язык вначале бы выучил на базовом уровне. Шестнадцатиричные константы начинаются с префикса 0х. Если х рассматривать как плейсхолдер, то тут префикс 0. А с префикса 0 начинаются восьмеричные константы. Т.ч. максимум, что может быть, это — 07.
Здравствуйте, Sni4ok, Вы писали:
S>Здравствуйте, Andrei F., Вы писали:
AF>>Похоже, что сборки мусора и/или многопоточности в стандарте не будет, а сам стандарт будет выпущен в лучшем случае в 2009 году. Результат вполне закономерный, я не удивлен.
S>то что не будет GC- слава богу, иначеб сделали из языка- помойку. S>А насчёт многопоточности- пофиг, буст он и в линуксе буст.
Бусту далеко до того, что будет в языке. В бусте нет:
WH>[/c#] WH>вылеты (в том числе с несколькими Set'ами и Reset'ами подряд) прекратились WH>однако начались зависания... что и не удивительно ибо см на ManagedThreadId'ы в твоем варианте.
В них как раз всё чудесно
WH>после изменения кода
Угу, обрезал суть — у тебя не попадёт дважды один и тот же тред на евент в первом варианте, а хотелось убедиться во всех сценариях прохода через евент, т.е. чтобы тред, получивший квант времени, опять застрял на AutoResetEvent в цикле. Там же очевидная причина возможных зависаний и вылетов — "грязный" способ завершения тредов в Main().
WH>чтд.
Угу, на стек-трейс посмотри
В моём упрощённом примере реализации евента на семафоре есть недостаток — в том, что нельзя вызывать Set когда и так уже в signaled state, и Reset если уже сброшен, т.к. я хотел лишь продемонстрировать логику выражения евента через семафор (ведь об этом шёл спор). Подобный многократный Set/Reset требует доп. флаг состояния в любом случае и синхронизация доступа к этому флагу.