Следующее дает мне Нарушение прав доступа в Windows 32-bit, dmd.2.052, без флагов.Когда деструктор запускается сборщиком мусора, окно сообщения кажется поврежденным в процессе.
import std.stdio;
import core.thread;
import core.memory;
import std.concurrency;
class C
{
string m_str;
Tid m_receiverTid;
this(string s, Tid rt) { this.m_str = s; this.m_receiverTid = rt; }
~this() { writeln("Destructor : ",this.m_str);
m_receiverTid.send(this.m_str);
}
}
void receiver() {
try {
while(true) {
receive((string s){writeln("Received: ",s);});
}
} catch (Throwable th) {
writeln("Caught throwable: ",th.toString());
}
}
void main() {
Tid receiverTid = spawn(&receiver);
receiverTid.send("Basic test");
Thread.sleep( 5_000_000 );
C c1 = new C("c1 Manually deleted",receiverTid);
delete c1;
Thread.sleep( 5_000_000 );
{
C c2 = new C("c2 Garbage collected",receiverTid);
}
writeln("Running garbage collector..."); // This line needed to flush out the c2 root pointer.
GC.collect();
Thread.sleep( 5_000_000 );
writeln("Exiting main thread...");
}
Выше приведено:
Получено: Базовый тест
Деструктор: c1 Удалено вручную
Получено: c1 Удалено вручную
Запущен сборщик мусора ...
Деструктор: c2 Сборка мусора
Получено: Сборка мусора c2
Поймано с возможностью выброса: object.Error: Нарушение прав доступа
Выход из основного потока ...
Есть ли обходные пути для этого?
Есть ли способ для кода деструктора узнать, вызывается ли он GC или нет?
Является ли передача сообщений от деструктора по сути небезопасной, например, если потоки, не относящиеся к GC, замораживаются GC, в то время как они имеют блокировку мьютекса в окне общего сообщения, тогда GC может зайти в тупик, если он отправляет сообщение в заблокированное окно сообщения?Или код деструктора выполняется только в цикле очистки после размораживания всех потоков?
Безопасно ли для деструктора ссылаться на локальное хранилище потока, например, может ли цикл очистки GC находиться в другом потоке?