amiga-news DEUTSCHE VERSION
.
Links| Forums| Comments| Report news
.
Chat| Polls| Newsticker| Archive
.

amiga-news.de Forum > Programmierung > Deadlock Problem [ - Search - New posts - Register - Login - ]

-1- [ - Post reply - ]

2004-07-09, 00:22 h

DariusBrewka
Posts: 899
[Banned user]
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

[ - Answer - Quote - Direct link - ]

2004-07-09, 02:28 h

geit
Posts: 332
[Former member]

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


[ - Answer - Quote - Direct link - ]

2004-07-09, 08:39 h

thomas
Posts: 7718
User

@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/

[ - Answer - Quote - Direct link - ]

2004-07-09, 12:38 h

Holger
Posts: 8116
User
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.

[ - Answer - Quote - Direct link - ]

2004-07-09, 13:29 h

platon42
Posts: 400
[Former member]
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

[ - Answer - Quote - Direct link - ]

2004-07-09, 14:56 h

bubblebobble
Posts: 707
User
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



[ - Answer - Quote - Direct link - ]

2004-07-09, 15:17 h

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

Darius

[ - Answer - Quote - Direct link - ]

2004-07-10, 20:24 h

Georg
Posts: 107
User
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.

[ - Answer - Quote - Direct link - ]

2004-07-10, 20:28 h

Georg
Posts: 107
User
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.






[ - Answer - Quote - Direct link - ]


-1- [ - Post reply - ]


amiga-news.de Forum > Programmierung > Deadlock Problem [ - Search - New posts - Register - Login - ]


.
Masthead | Privacy policy | Netiquette | Advertising | Contact
Copyright © 1998-2024 by amiga-news.de - all rights reserved.
.