Try-catch in Qt
-
Здравейте,
Аз лично много се радвам за създаването на този форум. Имам един-два въпроса.Понеже в Qt няма добре разработена Try-catch технология (има, но се препоръчва да не се използва), искам да задам въпроса как да се предпазваме от крашване поради някакви непредвидими, много рядко случващи се грешки като делене на нула или обръщение към вече изтрит обект? Даже имам и конкретен пример който трябва да реша:
Имам списък (QList) от обекти и един таймер, който цъка на всеки 500 msec. Той, ако не бъркам, работи в друга нишка и минава по всички обекти от списъка за да изпълни по един метод от тях. В основната нишка има методи за добавяне и изтриване на обекти към/от списъка.
Какво ще стане ако в момента на изпълнение на таймера, докато изпълнява метода на третия обект от списъка, от основната нишка бъде изтрит 8-мия обект от списъка? Програмата ще крашне защото ще бъде направен опит да се извика метод на несъществуващ вече обект. Ако в метода на таймера имаше Try-catch блок, щеше да реши проблема. Но няма.Как да избегнем такива ситуации? Какъв е механизма за защита от крашване в Qt?
-
Здравей,
Аз лично Try-catch концепцията не я харесвам особено. Може би защото съм повече С програмист, отколкото С++, а и за устройствата, за които пиша, try-catch се избягва заради мизериите, които прави по стека и прекаленото много допълителен код.
За указателите решението е да се проверяват преди употреба, за делението на 0 - или рънтайм проверки или асърти и стабилно тестване. Зависи от програмата и на какво ще върви. От това, което съм виждал в Qt и KDE кода, мога да кажа, че и те разчитат на проверки и асърти.
-
[quote author="task_struct" date="1312912088"]Здравей,
За указателите решението е да се проверяват преди употреба[/quote]А не е ли възможно, макар и веднъж на 1300 години да се получи така: Проверявам указателя и виждам че не е нула (обекта не е изтрит). Точно тогава превключва другата нишка в която точно този указател се изтрива. После проверката вече е минала и... "както си работеше и изведнъж ми изчезна програмата... ама аз нищо не правех, а тя изчезна"...
И друга ситуация - работя с предпоследния указател от списъка. Превключва другата нишка и изтрива последния от списъка. След това първата нишка продължава и прави опит да прочете следващия елемент от списъка (поради една или друга причина се използва for цикъл). Но такъв вече няма и... Изобщо не стигам до момента да проверя дали има такъв указател.
Сетих се и трети случай: проверил съм обекта и съм извикал един метод от него. Метода приключва и точно преди да извика втори метод другата нишка убива обекта. То май работата отива към семафори...
Досега за подобни ситуации при многонишкови програми винаги съм използвал Try-catch (за MS C++ програми, не Qt) и не съм го мислел много много, но сега в Qt-то се налага да го мисля това и нямам опит в предпазване от такива грешки.
Ок, значи няма някаква технология и трябва всеки сам да се спасява. А има ли някаква система за lock-ване или семафори или сам да си правя всичко?
-
[quote author="M_3_T" date="1312982224"] А има ли някаква система за lock-ване или семафори или сам да си правя всичко?[/quote]
Има, прегледай документацията: "QSemaphore":http://doc.qt.nokia.com/4.7/qsemaphore.html, "QMutex":http://doc.qt.nokia.com/latest/qmutex.html, "QReadWriteLock ":http://doc.qt.nokia.com/latest/qreadwritelock.html, "QWaitCondition":http://doc.qt.nokia.com/latest/qwaitcondition.html. За повече информация виж "тук":http://doc.qt.nokia.com/latest/threads-synchronizing.html
-
Аз доколкото знам Qt приложенията са еднонишкови, докато ти си създадеш нишки. EventLoop-а се изпълнява и той извиква слотовете, или слотовете се извикват там където има emit. Повечето класове в Qt не са създадени да са безопасни в многонишкова среда и за това, ако приложението ти ползва нишки трябва сам да си защитиш данните.