watki komunikacja miedzy obiektami a stos

0

Witam,
Mam maly problem,
Program dostaje SIGILL

Mam obiekt "a" ktory zapisuje sie do obiektu "b" w innym watku(nadrzednym) przekazujac jednoczesnie
referencje do samego siebie. b->subscribe(*this)

Jesli to na co sie zapisal jest dostepne obiekt w watku nadrzednym wywoluje "a->upd()" (a jest wskaznikiem bo przechowuje otrzymane referencje w obiekcie "b" jako std::vector<a*> )
tzn. proboje bo w tym momencie leci SIGILL,

Dlaczego mnie to zastanawia?
Bo jak wszystko pracowalo w jednym watku nie bylo problemow.
z tym ze nie przekazywalem *this ale b->subscirbe(&a).

Moze powinienem troche bardziej doczytac o watka,
system przydziela calkowicie nowa pamiec dla watku, ale mozliwe jest : b->subscribe(*this) wiec mimo iz obiekt "b" znajduje sie w innym watku jest poprawnie adresowany.

doczytalem tez ze SIGILL leci najczesciej jak nadpisuje adres powrotu z funkcji na stosie,
okej moze sie to zgadzac, ale dlaczego dzialalo
jesli oba obiekty "a" i "b" znajdowaly sie w tej samej przeztrzeni adresowej...(tzn. jako kompozycje w jednej klasie.?)

kazde wsparcie mile widziane.

0

system przydziela calkowicie nowa pamiec dla watku

Nie, system przydziela tylko stos, a ten leży w tej samej przestrzeni adresowej co inne wątki w procesie.

Podejrzewam, że problem leży w złej synchronizacji wątków (lub jej zupełnym braku).

0

trudno w ogole cokolewiek powiedziec, za malo kodu podales.. sprobuj uscislic swoj kod to tego konkretnego bledu, albo w ogole napisz przykladowy kodzik ktory zachowuje sie tak samo.

0

Dzieki za odpowiedzi,
ponizej kompiloawlny kod:
I to jest ten przypadek dla ktorego wszystko jest okej.

Ale jak widzimy Obserwator::upd()
jest wywolywany w srodku Obserwator::proceedSubscription()
I w przypadku watkow tutaj moze jest nadpisywany adres powrotu przechowywany na stosie?
Jesli tak to jak to "naprawic".

Czy jest mozliwosc asynchronicznego zapisyania?
Pozniej wygeneruje kod z watkami z ktorym sa problemy.
(teraz nadmienie ze gdy Obserwowany* b jest w watku nadrzednym
przy probie

void Obserwowany::updSubscribers()
{
   ...
        <u>(*it)->upd();</u>
  ....
};

system wysyla SIGILL.
Na konsoli nie pojawia sie oczywiscie komunikat z funkcji upd().

Czyli proba nadpisania adresu powrotu na stosie ...chyba..

#include <iostream>
#include <vector>

class Obserwowany;

class Obserwator
{
        public:
           Obserwator();
           Obserwator(Obserwowany *o);
            void upd();
            void proceedSubscription();

        private:
            Obserwowany &obs;
};



class Obserwowany
{
        public:
            void subscribe(Obserwator& a);

        private:
            std::vector<Obserwator*> obserwatorzy;

            void updSubscribers();
};


/***********MAIN*******************/

int main()
{
    Obserwowany* b = new  Obserwowany;
    Obserwator* a = new  Obserwator(b);

    a->proceedSubscription();

    delete a;
    delete b;
    std::system("PAUSE");
	return 0;
}


/***************DEFINICJE*******************/

Obserwator::Obserwator(Obserwowany *o):obs(*o){};
Obserwator::Obserwator():obs(){};

void Obserwator::upd()
{
        std::cout<<"UPD invoked"<<std::endl;
};

void Obserwator::proceedSubscription()
{
       std::cout<<"Obserwator::proceedSubscription()   STARTED"<<std::endl;
       obs.subscribe(*this);
       std::cout<<"Obserwator::proceedSubscription()   FINISHED"<<std::endl;
};


void Obserwowany::subscribe(Obserwator& a)
{
         std::cout<<"Subscription proceeded"<<std::endl;
        obserwatorzy.push_back(&a);
        this->updSubscribers();
};

void Obserwowany::updSubscribers()
{
    std::vector<Obserwator*>::iterator it;
    for(it=obserwatorzy.begin(); it!=obserwatorzy.end() ;++it)
        (*it)->upd();

    std::cout<<"updSubscriber() finished"<<std::endl;
};
0

cos krecisz.. ten kod nie ma prawa sie skompilowac z powodu linii:

class Obserwator
{....
        private:
            Obserwowany &obs;
};
...
Obserwator::Obserwator():obs(){};

poza tym, ten kod wygada ok. kiedy mowilem o kodzie, mialem na mysli kod 'z watkami' - po co nam ten skoro on dziala.. masz problem z tamtym, pokaz tamten. musiales skopac rozdzial na watki/synchronizacje..

0
quetzalcoatl napisał(a)

cos krecisz.. ten kod nie ma prawa sie skompilowac z powodu linii:

class Obserwator
{....
        private:
            Obserwowany &obs;
};
...
Obserwator::Obserwator():obs(){};

Nie krece...jesli nie wierzyz skompiluj ;-P
A to dlatego ze nie jest wywolywany kostruktor kopiujacy klasy Obserwowany tylko jej,
domyslny konstruktor i ustawia referencje "obs" na ten wlasnie nowo utworzony obiekt.
i wlasnie bez tej linijki kod sie nie skompiluje.

Tak jak pisalem, wyprodukuje ten kod z watkami w krotce,
tyle ze z synchronizaja nie moze byc problemow,
bo jest tylko jeden punkt dostepu...(czyli jest tylko jeden watek, ktory wywoluje ptr->upd())

0
bua napisał(a)
quetzalcoatl napisał(a)

cos krecisz.. ten kod nie ma prawa sie skompilowac z powodu linii:

class Obserwator
{....
        private:
            Obserwowany &obs;
};
...
Obserwator::Obserwator():obs(){};

Nie krece...jesli nie wierzyz skompiluj ;-P
A to dlatego ze nie jest wywolywany kostruktor kopiujacy klasy Obserwowany tylko jej,
domyslny konstruktor i ustawia referencje "obs" na ten wlasnie nowo utworzony obiekt.
i wlasnie bez tej linijki kod sie nie skompiluje.

W naglowku .h i w pliku .cpp istnieje konstruktor bezparametrowy, ktory pozostawia pole typu referencyjnego zainincjowane adresem 0x0000000. to nie powinno sie skompilowac. a CO NAJMNIEJ powinien dawac warninga ze zostawiasz null-reference, co jest smrodem (czyt.: bledem programisty) takim ze trudno o gorszy.. Twoj kompilator wyglada na dosc niedopracowany. co to jest? borland albo dev-cpp moze jak zwykle?

dowod - twoj kod po skompilowaniu pod g++:

-sh-3.00# g++ x.cpp
x.cpp: In constructor `Obserwator::Obserwator()':
x.cpp:51: warning: default-initialization of `Obserwowany&Obserwator::obs',
   which has reference type

* Dev-C++ używa G++ 3.4.2... * deus
//q: tak, ale dziwnym trafem z dev-cpp juz byly rozne dziwactwa ktorych w linuxowym g++ nie zauwazono.. nie jestem w stanie przytoczyc przykladu. po prostu pamietam ze byly rozne dziwy

0
quetzalcoatl napisał(a)

dev-cpp moze jak zwykle?

Ciekawe...ale nie wazne...

Nie dyskutujmy czy to dobre czy zle, powiem tyle ze chce zeby tam byla referencja do nulla...
jesli zostanie wywolany domyslny konstruktor.
PS. nie pisalem ze nie ma warningow... napisalem ze sie kompiluje

1 użytkowników online, w tym zalogowanych: 0, gości: 1