Portál AbcLinuxu, 17. května 2024 17:22


Dotaz: pthread_cancel

Jardík avatar 8.5.2010 22:40 Jardík | skóre: 40 | blog: jarda_bloguje
pthread_cancel
Přečteno: 321×
Odpovědět | Admin
Snažím se nastavit handler pro úklid dat ve vláknu, ale nějak se nedaří, GCC mi píše nějaký blbosti.
template<typename T>
class CancelableThreadData
{
	protected:
		bool _is_cleanup;
		T* _data;
		static void _cleanup_func(void* d);
	public:
		template<typename... T_args>
		CancelableThreadData(T_args... args);
		
		~CancelableThreadData();
		
		T* operator->() { return _data; }
		const T* operator->() const { return _data; }
		
		T& operator*() { return *_data; }
		const T& operator*() const { return *_data; }
};

template<typename T>
void CancelableThreadData<T>::_cleanup_func(void* d)
{
	((CancelableThreadData<T>*)(d))->_is_cleanup = true;
	((CancelableThreadData<T>*)(d))->~CancelableThreadData();
}

template<typename T>
template<typename... T_args>
CancelableThreadData<T>::CancelableThreadData(T_args... args)
{
	_is_cleanup = false;
	_data = new T(args...);
	pthread_cleanup_push(_cleanup_func, (void*)_data);
}

/* Line 272 */template<typename T>
CancelableThreadData<T>::~CancelableThreadData()
{
	if (!_is_cleanup) pthread_cleanup_pop(0);
	delete _data;
}

Výstup gcc:
Thread.h: In constructor ‘BurnLib::CancelableThreadData<T>::CancelableThreadData(T_args ...)’:
Thread.h:272:10: error: expected ‘while’ before ‘<’ token
Thread.h:272:10: error: expected ‘(’ before ‘<’ token
Thread.h:272:10: error: expected primary-expression before ‘<’ token
Thread.h:272:20: error: expected nested-name-specifier before ‘T’
Thread.h:272:20: error: expected ‘(’ before ‘T’
Thread.h:272:20: error: expected ‘)’ before ‘T’
Thread.h:272:20: error: expected ‘;’ before ‘T’
Thread.h:272:21: error: expected unqualified-id before ‘>’ token
Věřím v jednoho Boha.

Řešení dotazu:


Nástroje: Začni sledovat (0) ?Zašle upozornění na váš email při vložení nového komentáře.

Odpovědi

Jardík avatar 8.5.2010 23:18 Jardík | skóre: 40 | blog: jarda_bloguje
Rozbalit Rozbalit vše Re: pthread_cancel
Odpovědět | | Sbalit | Link | Blokovat | Admin
To voe, voni to jsou makra a ještě tak prasácký! Od kdy? Manuál mi tvrdí, že to jsou funkce a když kouknu do pthread.h, tak tam jsou samý makro-prasárny, až jsem se lekl.
Věřím v jednoho Boha.
8.5.2010 23:29 Sinuhet | skóre: 31
Rozbalit Rozbalit vše Re: pthread_cancel

Tak ten manual zahodte a poridte si lepsi:

These functions may be implemented as macros. The application shall ensure that they appear as statements, and in pairs within the same lexical scope (that is, the pthread_cleanup_push() macro may be thought to expand to a token list whose first token is '{' with pthread_cleanup_pop() expanding to a token list whose last token is the corresponding '}' ).
Jardík avatar 9.5.2010 00:04 Jardík | skóre: 40 | blog: jarda_bloguje
Rozbalit Rozbalit vše Re: pthread_cancel
Akorát nevím, proč jsem se s tím dělal, když jsem teď zjistil, že se mi zavolá destruktor objektu i při přímém zavolání pthread_exit, či při použití pthread_cancel. Jak to? Vždyť se přece nedostanu mimo scope (teda dostanu, ale kompilátor to přece nemůže věďet?).
Věřím v jednoho Boha.
Jardík avatar 9.5.2010 00:18 Jardík | skóre: 40 | blog: jarda_bloguje
Rozbalit Rozbalit vše Re: pthread_cancel
Na stránkách HP zase tvrdí, že C++ objekty uklízeny nejsou. Tak babo raď, u mě uklízeny jsou...?
Věřím v jednoho Boha.
Bluebear avatar 9.5.2010 00:34 Bluebear | skóre: 30 | blog: Bluebearův samožerblog | Praha
Rozbalit Rozbalit vše Re: pthread_cancel
Celou funkčnost POSIXových threadových funkcí zajišťuje libc (jsou to všechno wrappery nad clone(), pár dalšími voláními a signály); teoreticky to může být nějak ošetřené, aby se destruktory zavolaly, ale nespoléhal bych na to. Při představě použití se složitými objekty z C++, kde destruktor může provádět relativně komplikované akce, se mi ježí všechny chlupy; to se může volat ze signal handleru nebo s kdovíjakým kontextem, stačí jedno blbé volání a budeš to ladit až do důchodu.

Pokud to nutně potřebuješ, nezbývá než se podívat do zdrojáků libc - ale upozorňuji, že tato část libc bude na čtení opravdu *strašná*, protože jsou to wrappery snažící se splňovat POSIXový standard, který je naprosto padlý na hlavu, za pomoci POSIXových signálů, které jsou padlé na hlavu taky, a Linuxových callů, které sice možná nejsou úplně šílené, ale nejsou navrženy pro použití normálním člověkem, nýbrž pouze autory libc. Blicí pytlík povolen a doporučen.
To mi připomíná, jak jsem si pořídil květináč, že v něm budu mít květinu. Opravdu tam byla, ale potom být přestala...
Jardík avatar 9.5.2010 00:57 Jardík | skóre: 40 | blog: jarda_bloguje
Rozbalit Rozbalit vše Re: pthread_cancel
Problém zase je, že když na to nebudu spoléhat a použiju ten "obal", co jsem použil výše, tak se mi pak zase destruktor zavolá 2x, tak si hezky vybrat :-). Nakonec pak skončim u assembleru, kde budu alespoň vědět, co se stane :-)
Věřím v jednoho Boha.
Bluebear avatar 9.5.2010 01:14 Bluebear | skóre: 30 | blog: Bluebearův samožerblog | Praha
Rozbalit Rozbalit vše Re: pthread_cancel
Dynamicky alokované objekty to nesebere, to nesmí; takže v nejhorším tudy vede jakás takás cesta.

Vzhledem k tomu, že pthread_cleanup_push() vlastně začíná vlastní scope (protože obsahuje otevírací složenou závorku) a pthread_cleanup_pop() ho zase uzavírá, tak je představitelné (ale ne jisté), že pro objekty deklarované uvnitř toho scopu budou skutečně zavolány destruktory. Můžeš to zkusit; pokud to bude fungovat na Linuxu, snad by to mohlo být i přenositelné.

Zvážil bych ještě možnost vyloučit pthread_cancel() ze hry úplně a udělat komunikaci mezi těmi thready jinak (třeba pomocí signálů, ty se aspoň dají pochopit, nebo pomocí socketů či něčeho takového).
To mi připomíná, jak jsem si pořídil květináč, že v něm budu mít květinu. Opravdu tam byla, ale potom být přestala...
Jardík avatar 9.5.2010 13:13 Jardík | skóre: 40 | blog: jarda_bloguje
Rozbalit Rozbalit vše Re: pthread_cancel
Ale ono i když pthread_cleanup_push() nepoužiju a ten objekt je ve scopu té funkce, kde se začíná vykonávat thread, tak po pthread_cancel i pthread_exit se mi ty destruktory zavolají, jakoby tam byl nějaký "zvláštní" mechanismus pro úklid. Něco jsem našel tu:
Unlike some other implementations of threads, C++ destructors for automatic objects are allowed to run in a well defined and consistent manner when a thread is terminated.

....

When a thread terminates, the following occurs: If the thread was ended using pthread_exit(), pthread_cancel() or return from the thread start routine, then cancellation cleanup handlers and data destructors are run.
The thread is terminated. At the time that the thread is terminated, both C++ destructors for automatic objects and AS/400 cancel handlers run.
Věřím v jednoho Boha.
Jardík avatar 9.5.2010 00:06 Jardík | skóre: 40 | blog: jarda_bloguje
Rozbalit Rozbalit vše Re: pthread_cancel
Jinak našel jsem to tam taky, ale proč mi na začátku tvrdí "these functions" a na konci (kde to nečtu :-)) mi řeknou, že to můžou být makra ...
Věřím v jednoho Boha.
Bluebear avatar 9.5.2010 00:37 Bluebear | skóre: 30 | blog: Bluebearův samožerblog | Praha
Rozbalit Rozbalit vše Re: pthread_cancel
Možná proto, aby čtenář nezešílel už při prvních řádcích. POSIXové thready je nutné člověku vysvětlovat pomalu a opatrně, jinak hrozí psychická újma.
To mi připomíná, jak jsem si pořídil květináč, že v něm budu mít květinu. Opravdu tam byla, ale potom být přestala...

Založit nové vláknoNahoru

Tiskni Sdílej: Linkuj Jaggni to Vybrali.sme.sk Google Del.icio.us Facebook

ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.