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 |
Generic queue in C (thread safe)
#1
Posted 15 April 2016 - 19:09
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 L-am pus ca fisier .txt ca .h nu-mi da voie forumul. Attached FilesEdited by EnachescuAlin, 15 April 2016 - 19:12. |
#2
Posted 15 April 2016 - 22:00
/** * 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
Posted 15 April 2016 - 22:39
dani.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. dani.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); #endifMi 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. 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. dani.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. 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. dani.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? dani.user, on 15 aprilie 2016 - 22:00, said: #ifdef __linux pthread_mutex_t *mutex; #endifCum realizezi sincronizarea e un detaliu de implementare (care depinde foarte mult si de platforma). Nu ar trebui dezvaluit in header (hint: structuri opace). dani.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? dani.user, on 15 aprilie 2016 - 22:00, said: #ifdef __linux #include <pthread.h> #endifDaca tot e open-source, pacat sa fie Linux-only. Mai ales avand in vedere ca pthread e disponibil si pe alte platforme. dani.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 Multumesc mult pentru review |
#4
Posted 15 April 2016 - 22:48
EnachescuAlin, 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. EnachescuAlin, 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. EnachescuAlin, 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. EnachescuAlin, 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. EnachescuAlin, 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
Posted 16 April 2016 - 06:39
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
▶ 0 user(s) are reading this topic
0 members, 0 guests, 0 anonymous users