Jump to content

SUBIECTE NOI
« 1 / 5 »
RSS
Cum sterg mails din Promotions

Vanzare cumparare fara transfer b...

Receptie ciudata, in functie de t...

Dupa 20 ani de facultate, am uita...
 Mobile.de ofera imprumut de bani ...

problema test grila

Digi24 a disparut de pe TV Lg

Drept de proprietate intelectuala...
 Jante noi shitbox

Trinitas TV 4K

Dacia 1316 cu 6 usi ...

Frecventa modificata radio
 Un nou pericol pt batrani

Ar trebui sa vindem imobiliarele ...

Dupa renuntarea la aparat dentar

pelerinaj in Balcik
 

Generic queue in C (thread safe)

- - - - -
  • Please log in to reply
4 replies to this topic

#1
EnachescuAlin

EnachescuAlin

    Active Member

  • Grup: Members
  • Posts: 1,008
  • Înscris: 08.07.2013
Salutare!
M-am gandit sa fac o coada generica in C si sa fie si thread safe. Deocamdata am facut doar headerul si voiam sa primesc review la cum am gandit coada.
Am incercat sa pun codul, dar il strica tag-ul code si nu mai arata asa clar.
Asa ca va las fisierul Posted Image L-am pus ca fisier .txt ca .h nu-mi da voie forumul.

Attached Files

  • Attached File  q.txt   8.03K   34 downloads

Edited by EnachescuAlin, 15 April 2016 - 19:12.


#2
dani.user

dani.user

    Guru Member

  • Grup: Senior Members
  • Posts: 30,239
  • Înscris: 24.02.2007
/**
 * The queue will be stored in the memory like a forward list.
 */


Lipseste un element important inainte de a putea defini coada cu adevarat generica: posibilitatea utilizarii oricarei structuri de date. O coada pana la urma nici nu e o structura de date propriu-zisa, ci doar ofera un subset de functionalitate a unei structuri mai generice.

#ifdef PhiLib_QUEUE_FREE_FUNCTION
QUEUE_ERROR_CODE queue_delete(__IN__ QUEUE*		 __queue,
							  __IN__ QueueFreeFn	__freeFn);
#else
QUEUE_ERROR_CODE queue_delete(__IN__ QUEUE*		 __queue);
#endif


Mi se pare ca ai abuzat de macro-uri, intr-un mod inflexibil. De exemplu, poate vreau o instanta sa o pot sterge printr-o functie custom pe cand altele sa foloseasca metoda default. Abordarea ta ma obliga sa aleg un mod si sa-l pastrez in acelasi proiect.

#if (defined PhiLib_QUEUE_LIMIT) || (defined PhiLib_QUEUE_LENGTH)


Numele imi indica ca ar trebui sa definesc niste valori, insa tu defapt verifici doar daca doresc limite. In acest caz, prezenta _HAS_ in nume ar fi fost mult mai sugestiva.
Insa si aceasta abordare sufera de aceeasi problema ca mai sus.

Daca singurul motiv pentru care nu ai inclus by default aceste valori este sa economisesti cativa bytes in structura, solutia mult mai eleganta ar fi sa definesti doua structuri.

QUEUE_ERROR_CODE queue_front_wait(__IN__  QUEUE*		__queue,
								  __OUT__ QUEUE_DATA*   __data);


Cand ai 5 threaduri care asteapt sa apara un element, care din ele e notificat cand unul e introdus?

#ifdef __linux
	pthread_mutex_t *mutex;
#endif


Cum realizezi sincronizarea e un detaliu de implementare (care depinde foarte mult si de platforma). Nu ar trebui dezvaluit in header (hint: structuri opace).

	QUEUE_LOCK_ERROR			= -7,
	QUEUE_UNLOCK_ERROR		  = -8,
	QUEUE_MUTEX_INIT_ERROR	  = -9,
	QUEUE_MUTEX_DESTROY_ERROR   = -10,

	QUEUE_COND_INIT_ERROR	   = -11,
	QUEUE_COND_DESTROY_ERROR	= -12,
	QUEUE_COND_WAIT_ERROR	   = -13,
	QUEUE_COND_SIGNAL_ERROR	 = -14,

	QUEUE_WAS_REMOVED		   = -15,


Mult prea detaliate cauzele erorilor. Din moment ce ma bazez pe codul tau pentru a obtine thread-safety, nu vad de ce m-ar interesa exact codul de eroare returnat de mecanismul tau de sincronizare. In plus, daca maine treci pe un sistem lock-free? Stergi toate acele coduri fiindca devin obsolete?

#ifdef __linux
#include <pthread.h>
#endif


Daca tot e open-source, pacat sa fie Linux-only. Mai ales avand in vedere ca pthread e disponibil si pe alte platforme.

/**
 * If is defined PhiLib_QUEUE_LIMIT then the limit of the queue is stored in
 * the her memory.
 */


Un mic upgrade la limba engleza nu strica :)

#3
EnachescuAlin

EnachescuAlin

    Active Member

  • Grup: Members
  • Posts: 1,008
  • Înscris: 08.07.2013

View Postdani.user, on 15 aprilie 2016 - 22:00, said:

/**
* The queue will be stored in the memory like a forward list.
*/

Lipseste un element important inainte de a putea defini coada cu adevarat generica: posibilitatea utilizarii oricarei structuri de date. O coada pana la urma nici nu e o structura de date propriu-zisa, ci doar ofera un subset de functionalitate a unei structuri mai generice.
Nu stiu daca chiar e util...adica cum ar arata o coada care sa fie salvata in memorie ca un arbore binar?

View Postdani.user, on 15 aprilie 2016 - 22:00, said:

#ifdef PhiLib_QUEUE_FREE_FUNCTION
QUEUE_ERROR_CODE queue_delete(__IN__ QUEUE* __queue,
__IN__ QueueFreeFn __freeFn);
#else
QUEUE_ERROR_CODE queue_delete(__IN__ QUEUE* __queue);
#endif

Mi se pare ca ai abuzat de macro-uri, intr-un mod inflexibil. De exemplu, poate vreau o instanta sa o pot sterge printr-o functie custom pe cand altele sa foloseasca metoda default. Abordarea ta ma obliga sa aleg un mod si sa-l pastrez in acelasi proiect.
Daca prin metoda default te referi la free() nu inteleg ce te opresesti...
Adica functia aia poti s-o apelezi in 3 feluri:
queue_delete(&queue, MyFreeFunction);
queue_delete(&queue, free);
queue_delete(&queue, NULL);

Si cand apelezi cu NULL nu va apela nicio functie.

View Postdani.user, on 15 aprilie 2016 - 22:00, said:

#if (defined PhiLib_QUEUE_LIMIT) || (defined PhiLib_QUEUE_LENGTH)

Numele imi indica ca ar trebui sa definesc niste valori, insa tu defapt verifici doar daca doresc limite. In acest caz, prezenta _HAS_ in nume ar fi fost mult mai sugestiva.
Insa si aceasta abordare sufera de aceeasi problema ca mai sus.
Daca singurul motiv pentru care nu ai inclus by default aceste valori este sa economisesti cativa bytes in structura, solutia mult mai eleganta ar fi sa definesti doua structuri.
Nu cred ca solutia cea mai eleganta ar fi fost sa definesc 2 structuri pentru ca scriam mult cod de 2 ori. Si exista 2 solutii:
1. generezi 2 biblioteci, una in care coada are limita, si alta in care coada n-are limita.
2. daca nu-ti pasa de aia 8bytes poti sa apelezi queue_init(&queue, 0). Cozile care au limita 0 inseamna ca n-au limita.

View Postdani.user, on 15 aprilie 2016 - 22:00, said:

QUEUE_ERROR_CODE queue_front_wait(__IN__ QUEUE* __queue,
__OUT__ QUEUE_DATA* __data);

Cand ai 5 threaduri care asteapt sa apara un element, care din ele e notificat cand unul e introdus?
Sistemul de operare e sefu'...pentru moment o sa specific asta in documentatie, iar pe viitor o sa ma gandesc sa spui tu cu un define cum vrei sa fie...sa fie notificat ala care a inceput primul sa astepte sau ala care are prioritate mai mare etc...

View Postdani.user, on 15 aprilie 2016 - 22:00, said:

#ifdef __linux
pthread_mutex_t *mutex;
#endif

Cum realizezi sincronizarea e un detaliu de implementare (care depinde foarte mult si de platforma). Nu ar trebui dezvaluit in header (hint: structuri opace).
O sa ma documentez...

View Postdani.user, on 15 aprilie 2016 - 22:00, said:

QUEUE_LOCK_ERROR = -7,
QUEUE_UNLOCK_ERROR = -8,
QUEUE_MUTEX_INIT_ERROR = -9,
QUEUE_MUTEX_DESTROY_ERROR = -10,
QUEUE_COND_INIT_ERROR = -11,
QUEUE_COND_DESTROY_ERROR = -12,
QUEUE_COND_WAIT_ERROR = -13,
QUEUE_COND_SIGNAL_ERROR = -14,
QUEUE_WAS_REMOVED = -15,

Mult prea detaliate cauzele erorilor. Din moment ce ma bazez pe codul tau pentru a obtine thread-safety, nu vad de ce m-ar interesa exact codul de eroare returnat de mecanismul tau de sincronizare. In plus, daca maine treci pe un sistem lock-free? Stergi toate acele coduri fiindca devin obsolete?
C-ul nu te obliga sa bagi in seama ce iti returneaza o functie, daca te intereseaza te uiti, daca nu te intereseaza nu bagi in seama codul de eroare. Daca maine as trece pe sistem lock-free as sterge acele coduri doar pe versiunea pentru sistemul respectiv.

View Postdani.user, on 15 aprilie 2016 - 22:00, said:

#ifdef __linux
#include <pthread.h>
#endif

Daca tot e open-source, pacat sa fie Linux-only. Mai ales avand in vedere ca pthread e disponibil si pe alte platforme.
Momentan lucrez doar pe Linux, dar recunosc ca as vrea sa mearga si pe Windows, dar sa folosesc winapi nu pthread, pentru ca as vrea sa ma joc si cu api-ul Windows-ului.

View Postdani.user, on 15 aprilie 2016 - 22:00, said:

/**
* If is defined PhiLib_QUEUE_LIMIT then the limit of the queue is stored in
* the her memory.
*/

Un mic upgrade la limba engleza nu strica
Asa-i Posted Image
Multumesc mult pentru review Posted Image

#4
dani.user

dani.user

    Guru Member

  • Grup: Senior Members
  • Posts: 30,239
  • Înscris: 24.02.2007

View PostEnachescuAlin, on 15 aprilie 2016 - 22:39, said:

Nu stiu daca chiar e util...adica cum ar arata o coada care sa fie salvata in memorie ca un arbore binar?

Vector VS Lista inlantuita. Foarte utile ambele in diverse situatii.

View PostEnachescuAlin, on 15 aprilie 2016 - 22:39, said:

Daca prin metoda default te referi la free() nu inteleg ce te opresesti...
Adica functia aia poti s-o apelezi in 3 feluri:
queue_delete(&queue, MyFreeFunction);
queue_delete(&queue, free);
queue_delete(&queue, NULL);

Si cand apelezi cu NULL nu va apela nicio functie.

Problema e ca-mi dai sa aleg prea multe aspecte care n-ar trebui sa ma intereseze. quote_delete(pointer), quote_delete_custom(pointer, functie custom) ar fi mult mai curat, fara sa stau sa ma gandesc daca trebuie sa definesc vreun macro sau nu.
Daca adaptezi insa codul sa poata suporta o structura generica de date, probabil vei schimba si logica de delete.

View PostEnachescuAlin, on 15 aprilie 2016 - 22:39, said:

Nu cred ca solutia cea mai eleganta ar fi fost sa definesc 2 structuri pentru ca scriam mult cod de 2 ori. Si exista 2 solutii:

Foarte putin cod scriai de 2 ori. Mostenire exista si in C.

View PostEnachescuAlin, on 15 aprilie 2016 - 22:39, said:

Sistemul de operare e sefu'...pentru moment o sa specific asta in documentatie, iar pe viitor o sa ma gandesc sa spui tu cu un define cum vrei sa fie...sa fie notificat ala care a inceput primul sa astepte sau ala care are prioritate mai mare etc...

Unpredictable behavior is bad. Mai natural mi s-ar parea sa fie toata lumea notificata.

View PostEnachescuAlin, on 15 aprilie 2016 - 22:39, said:

C-ul nu te obliga sa bagi in seama ce iti returneaza o functie, daca te intereseaza te uiti, daca nu te intereseaza nu bagi in seama codul de eroare. Daca maine as trece pe sistem lock-free as sterge acele coduri doar pe versiunea pentru sistemul respectiv.

Un API e frumos sa fie stabil, cand vi cu versiunea 1.1 sa nu ma pui sa-mi recompilez codul meu doar fiindca ai facut schimbari minore.

Edited by dani.user, 15 April 2016 - 22:49.


#5
OriginalCopy

OriginalCopy

    I'm harmful, fear me please! :))

  • Grup: Senior Members
  • Posts: 27,268
  • Înscris: 10.08.2006
Cred ca ar merita sa arunci o privire pe disruptor: https://lmax-exchang...b.io/disruptor/

Interesante sunt dintre acele linkuri "Disruptor Technical Paper" si "Martin Fowler's Technical Review".

Exista implementari si in C.

Anunturi

Chirurgia spinală minim invazivă Chirurgia spinală minim invazivă

Chirurgia spinală minim invazivă oferă pacienților oportunitatea unui tratament eficient, permițându-le o recuperare ultra rapidă și nu în ultimul rând minimizând leziunile induse chirurgical.

Echipa noastră utilizează un spectru larg de tehnici minim invazive, din care enumerăm câteva: endoscopia cu variantele ei (transnazală, transtoracică, transmusculară, etc), microscopul operator, abordurile trans tubulare și nu în ultimul rând infiltrațiile la toate nivelurile coloanei vertebrale.

www.neurohope.ro

0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users

Forumul Softpedia foloseste "cookies" pentru a imbunatati experienta utilizatorilor Accept
Pentru detalii si optiuni legate de cookies si datele personale, consultati Politica de utilizare cookies si Politica de confidentialitate