amiga-news ENGLISH VERSION
.
Links| Forum| Kommentare| News melden
.
Chat| Umfragen| Newsticker| Archiv
.

amiga-news.de Forum > Programmierung > Deadlock Problem [ - Suche - Neue Beiträge - Registrieren - Login - ]

-1- [ - Beitrag schreiben - ]

09.07.2004, 00:22 Uhr

DariusBrewka
Posts: 899
[Benutzer gesperrt]
Hi, ich habe ein Programm, welches einen zweiten Thread erzeugt was auch Wunderbar funktioniert nur muss dieser Thread dem Hauptprogramm Nachrichten schicken und das Hauptprogramm kann wiederrum dem Thread Nachrichten schicken. Leider kommt es wie es kommen muss, dass beide auf einmal Nachrichten schicken wollen und dann beide Tasks auf Antwort warten, die Natürlich nicht kommt und das ganze endet in einem Deadlock.

Hat jemand Ahnung, wie das Problem beseitigt werden kann

gruss

[ - Antworten - Zitieren - Direktlink - ]

09.07.2004, 02:28 Uhr

geit
Posts: 332
[Ex-Mitglied]

Wenn Du die normalen PutMsg/ GetMsg der Exec.lib benutzt passiert das garantiert nicht.

Du mußt allerdings den PutMsg() zwischen Forbit()/Permit(), sonst passiert im besten Fall das was Du beschrieben hast. Im schlimsten Fall knallt es.

Du mußt/solltest außerdem vor dem Verschicken den MessageTyp auf NT_MESSAGE setzen. Die Messages sollten natürlich auch freigegeben werden, sonst bekommst Du ein Speichermangelproblem, was auch ein Deadlock erzeugen kann.

Verpassen kannst Du die Nachrichten auf keinen Fall, da sie jeweils am Port anhängen, bis Du sie abholst.

Mehr kann ich nicht sagen, ohne genauere Infos zum Übertragungsweg zu haben.

Guido Mersmann


[ - Antworten - Zitieren - Direktlink - ]

09.07.2004, 08:39 Uhr

thomas
Posts: 7716
Nutzer

@Darius:

Du beschreibst zu wenig, was du gemacht hast.

Ich vermute mal, es läuft folgendermaßen:

SubTask:
PutMsg (submsg,mainport);
Waitport(subreply)

Maintask:
PutMsg (mainmsg,subport);
WaitPort (mainreply);

Und jetzt warten beide auf ihren Reply-Port und nichts passiert.

Du solltest statt WaitPort() Wait() benutzen, mit mehreren Signalen:

SubTask:
subportsig = 1L << subport->mp_SigBit;
subreplysig = 1L << subrelpy->mp_sigBit;
received = Wait (subportsig | subreplysig);
if (received & subportsig)
{
/* neue Message verarbeiten */
}
if (received & subreplysig)
{
/* Antwort vom Hauptprogramm verarbeiten */
}

Und im Hauptprogramm entsprechend das selbe. So kann nie ein Deadlock auftreten, weil der Task bei jedem Signal aufwacht und nicht auf ein bestimmtes wartet, das gerade nicht auftreten kann.

Gruß Thomas

--
Email: thomas-rapp@web.de
Home: home.t-online.de/home/thomas-rapp/

[ - Antworten - Zitieren - Direktlink - ]

09.07.2004, 12:38 Uhr

Holger
Posts: 8116
Nutzer
Neben der von thomas beschriebenen Variante, auf beide Ports zu hören, gibt es natürlich noch eine einfachere Variante: verwende nur einen port pro task, der sowohl für die Nachrichten des anderen, als auch Antworten auf die eigenen verwendet wird.
Wenn Du, je nachdem wofür die Nachrichten eigentlich gut sind, an dieser Stelle kein paralleles Versenden zulassen willst, solltest Du eine Semaphore verwenden.

mfg
--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

09.07.2004, 13:29 Uhr

platon42
Posts: 400
[Ex-Mitglied]
Zitat:
Original von geit:
Du mußt allerdings den PutMsg() zwischen Forbit()/Permit(), sonst passiert im besten Fall das was Du beschrieben hast. Im schlimsten Fall knallt es.


AFAIK sind PutMsg(), ReplyMsg() und GetMsg() bereits Disable()/Enable() geschützt. Forbid()/Permit() braucht man eigentlich nur, wenn man mit Remove() bzw. AddTail() auf den MsgPorts direkt arbeitet (aus welchen Gründen auch immer).
--
--
Best Regards

Chris Hodges

[ - Antworten - Zitieren - Direktlink - ]

09.07.2004, 14:56 Uhr

bubblebobble
Posts: 707
Nutzer
Dein Program muss einfach nur in der Lage sein,
nachdem es eine Message abgeschickt hat, auch weiterhin
einkommende Messages zu bearbeiten, auch wenn die abgeschickte
noch nicht replied ist. Also nie explizit auf das Reply warten,
das Reply muss im Haupt Loop bearbeitet werden.


--
Thilo Köhler, Author von:
HD-Rec, Samplemanager, ArTKanoid, Monkeyscript, Toadies, AsteroidsTR, TuiTED, PosTED, UDM, TKPlayer, TKUnpacker
Homepage: http://www.hd-rec.de



[ - Antworten - Zitieren - Direktlink - ]

09.07.2004, 15:17 Uhr

DariusBrewka
Posts: 899
[Benutzer gesperrt]
Danke an alle, werde mal schauen welche Vorgehensweise die Beste ist, bzw. eigentlich gibt's nur eine Lösung.

Darius

[ - Antworten - Zitieren - Direktlink - ]

10.07.2004, 20:24 Uhr

Georg
Posts: 107
Nutzer
Zitat:
Original von geit:

Du mußt allerdings den PutMsg() zwischen Forbit()/Permit(), sonst passiert im besten Fall das was Du beschrieben hast. Im schlimsten Fall knallt es.


Wo hast du den das aufgeschnappt? ;-) Das braucht man nicht zu machen. In normalen Fällen. Nur wenn der Zielport (bzw. dessen Programm) evtl. "verschwinden" kann, noch während man die Message abschickt. Wie bei ARexx, wo man dann in etwa das ganze so abschützt:

Forbid();
if ((port = FindPort(portname))))
{
PutMsg(port, message);
}
Permit();

if (port)
{
/* Message erfolgreich verschickt. Dementsprechend fortfahren,
z. B. auf replymsg warten */
}
else
{
/* Message konnte nicht verschickt werden */
}

Zitat:
Du mußt/solltest außerdem vor dem Verschicken den MessageTyp auf NT_MESSAGE setzen.
.

PutMsg() macht das intern selbst.

[ - Antworten - Zitieren - Direktlink - ]

10.07.2004, 20:28 Uhr

Georg
Posts: 107
Nutzer
Zitat:
AFAIK sind PutMsg(), ReplyMsg() und GetMsg() bereits Disable()/Enable() geschützt.

Ja, sind sie. Weil sie aus Interrupts heraus benutzt werden können. Z. B. wenn ein Device IORequests in nem Interrupt handlet und zurückschickt.






[ - Antworten - Zitieren - Direktlink - ]


-1- [ - Beitrag schreiben - ]


amiga-news.de Forum > Programmierung > Deadlock Problem [ - Suche - Neue Beiträge - Registrieren - Login - ]


.
Impressum | Datenschutzerklärung | Netiquette | Werbung | Kontakt
Copyright © 1998-2024 by amiga-news.de - alle Rechte vorbehalten.
.