Сообщение, передаваемое из деструктора во время сборки мусора

Следующее дает мне нарушение прав доступа в 32-битной Windows, 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...");
}

Приведенное выше дает:

Получено: Базовый тест
окно сообщения кажется поврежденным в процессе. import ...

Следующее дает мне нарушение прав доступа в 32-битной Windows, 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...");
}

Приведенное выше дает:

Получено: Базовый тест
окно сообщения кажется поврежденным в процессе. import ...

Следующее дает мне нарушение прав доступа в 32-битной Windows, 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 Сборщик мусора
Поймано метательное: объект. Ошибка: нарушение прав доступа
Выход из основного потока ...

Есть ли обходные пути для этого?
Есть ли способ для кода деструктора узнать, вызывается он сборщиком мусора или нет?
Является ли передача сообщений от деструктора внутренне небезопасной, например, если потоки, отличные от GC, замораживаются сборщиком мусора, в то время как у них есть мьютекс-блокировка в общем окне сообщения, тогда сборщик мусора может заблокироваться, если он отправляет заблокированное окно сообщения? Или код деструктора выполняется только в цикле очистки после размораживания всех потоков?
Безопасно ли для деструктора ссылаться на локальное хранилище потока, например, может ли цикл очистки GC быть в другом потоке?

5
задан John 23 April 2011 в 01:19
поделиться