Thread Safety

Συζητήσεις για την γλώσσα C και C++

Συντονιστές: WebDev Moderators, Super-Moderators

Απάντηση
lakritidis
Δημοσιεύσεις: 401
Εγγραφή: 04 Αύγ 2005 14:35
Τοποθεσία: Katerini
Επικοινωνία:

Thread Safety

Δημοσίευση από lakritidis » 19 Φεβ 2009 21:06

Έχουμε έναν prethreaded server που έχει δημιουργεί κατά την εκκίνησή του 16 threads. Καθε ένα από αυτά καλεί μια συνάρτηση που εξάγει τα urls από ένα char buffer (τον html κώδικα μιας σελίδας) καi τα σώζει σε ένα νέο buffer της μορφής
url1<url2<url3<...<urln

Είναι η παρακάτω συνάρτηση thread safe?

Κώδικας: Επιλογή όλων

char *ExtractURLs&#40;char *base, char *Input&#41; &#123;

	char *result = &#40;char*&#41;malloc&#40;MAXLINE * sizeof&#40;char&#41;&#41;;
//	printf&#40;"%s\n\n\n", Input&#41;; fflush&#40;NULL&#41;;
	static int pos = 0, y = 0, spos = 0, epos = 0;
	static int len = strlen&#40;Input&#41;;
	char link&#91;1024&#93;;
	static int links = 0;
//printf&#40;"New Page\n"&#41;; fflush&#40;NULL&#41;;
	for &#40;pos = 0; pos < len; pos++&#41; &#123;
		
		if &#40;Input&#91;pos&#93; == 60&#41; &#123;
			if &#40;pos < len&#41; &#123;
				if &#40;&#40;Input&#91;pos + 1&#93; == 65 || Input&#91;pos + 1&#93; == 97&#41; && // a or A
					Input&#91;pos + 2&#93; == 32&#41; &#123; // space

					while &#40;Input&#91;pos&#93; != 62 && pos < len&#41; &#123;
						if &#40;&#40;Input&#91;pos&#93; == 72 || Input&#91;pos&#93; == 104&#41; && // h or H
						&#40;Input&#91;pos + 1&#93; == 82 || Input&#91;pos + 1&#93; == 114&#41; && // r or R
						&#40;Input&#91;pos + 2&#93; == 69 || Input&#91;pos + 2&#93; == 101&#41; && // e or E
						&#40;Input&#91;pos + 3&#93; == 70 || Input&#91;pos + 3&#93; == 102&#41; && // f or F
						&#40;Input&#91;pos + 4&#93; == 32 || Input&#91;pos + 4&#93; == 61&#41;&#41; &#123; // space or =
							pos = pos + 5;
							spos = pos;

							while &#40;Input&#91;pos&#93; != 62 && Input&#91;pos&#93; != 32 && pos < len&#41; &#123;
								pos++;
							&#125;
							epos = pos;
							int x = 0;
							for &#40;y = spos; y < epos; y++&#41; &#123;
								// Characters not allowed in URI &#40;RFC 2396&#41;
								if &#40;Input&#91;y&#93; > 32 &&  // space
									Input&#91;y&#93; != 34 && // ' &#40;single quote&#41;
									Input&#91;y&#93; != 39 && // " &#40;double quotes&#41;
									Input&#91;y&#93; != 60 && // < &#40;gt&#41;
									Input&#91;y&#93; != 62&#41; &#123; // > &#40;lt&#41;
										link&#91;x&#93; = Input&#91;y&#93;;
										x++;
								&#125;
							&#125;
							
							link&#91;x&#93; = 0; // zero terminate uri
							// Resolve URI&#58; Convert Relative scheme to absolute
							// according to RFC &#40;2396&#41;
//							printf &#40;"converting..."&#41;; fflush&#40;NULL&#41;;	
							char *abs = xmlBuildURI&#40;&#40;const char*&#41;link, &#40;const char*&#41;base&#41;;
//							printf &#40;"converted. Copying %s &#40;rel&#58;%s&#41; to result buffer &#40;%d&#41;... ", abs, link, strlen&#40;*result&#41;&#41;; fflush&#40;NULL&#41;;	
							if &#40;abs != NULL&#41; &#123;
								if &#40;links == 0&#41; &#123;
									strcpy&#40;result, abs&#41;;
									strcat&#40;result, ">"&#41;;
								&#125; else &#123;
									strcat&#40;result, abs&#41;;
									strcat&#40;result, ">"&#41;;
								&#125;
//								printf&#40;"Copied\n. Freeing..."&#41;; fflush&#40;NULL&#41;;
								links++;

								free&#40;abs&#41;;
//								printf&#40;"freed\n"&#41;; fflush&#40;NULL&#41;;
							&#125;
							break;
						&#125;
						pos++;
					&#125;
				&#125;
			&#125;
		&#125;
	&#125;
return&#40;result&#41;;
&#125;
Τελευταία επεξεργασία από το μέλος lakritidis την 20 Φεβ 2009 00:47, έχει επεξεργασθεί 1 φορά συνολικά.

Άβαταρ μέλους
soteres2002
S. & H. Moderator
Δημοσιεύσεις: 1524
Εγγραφή: 05 Μαρ 2004 22:17
Τοποθεσία: Ιωάννινα

Thread Safety

Δημοσίευση από soteres2002 » 19 Φεβ 2009 22:28

lakritidis έγραψε:

Κώδικας: Επιλογή όλων

   char *abs = xmlBuildURI&#40;&#40;const char*&#41;link, &#40;const char*&#41;base&#41;;
το καθαρό body είναι TS, αλλά συνολικά αυτόπ εξαρτάται από το αν είναι thread-safe και η xmlBuildURI(). Btw, άν βάλεις ένα -D_DREENTRANT symbol κατά τη μεταγλώττιση (άν ο σέρβερ χρησιμοποιεί posix threads), όλες οι τετριμμένες κλήσεις συστήματος που δεν είναι thread-safe ισοδυναμούν με κλήσεις των αντίστοιχων thread-safe εκδόσεων τους. Αν η συνάρτησή σου χρησιμοποιεί κοινούς πόρους πχ κάποιες global μεταβλητές για τα στατιστικά του σερβερ, τότε η συν. θα είναι ΤS αρκεί να χρησιμοποιήσεις σωστά mutex locking και ίσως σήματα.

lakritidis
Δημοσιεύσεις: 401
Εγγραφή: 04 Αύγ 2005 14:35
Τοποθεσία: Katerini
Επικοινωνία:

Thread Safety

Δημοσίευση από lakritidis » 20 Φεβ 2009 00:37

Φίλε Soteres ευχαριστώ για τη γρήγορη απάντηση.

Όχι η function δεν έχει πρόσβαση και δεν τροποποιεί shared variables και άρα δε χρειάζονται mutex locks. Έχω καταλάβει τι παίζει με τις shared μεταβλητές και τα mutual exclusions. Όμως με τα thread specific data ξέρω ότι πρέπει να χρησιμοποιηθεί η pthread_key_create ώστε να κάνουμε init ένα key το οποίο χαρακτηρίζει ένα pointer σε thread specific data. Και στη συνέχεια την pthread_setspecific ώστε να αντιστοιχίσουμε το κλειδι με τα data.

Και ρωτάω: δεν είναι η μεταβλητή result (αυτή που επιστρέφει η function) thread specific?

PS: Η xmlBuildURI μετατρέπει ένα relative URI σε absolute. Επιεδή βαριόμουν να διαβάσω τις 39 σελίδες του RFC 2396 πήρα copy-paste την xmlBuildURI από την libxml. Από ότι λέει εδώ η libxml είναι thread-safe. Η ExtractURLs βέβαια χρειάζεται επέκταση ώστε να "ξετρυπώνει" URLs που είναι κρυμμένα σε javascripts κτλ.

lakritidis
Δημοσιεύσεις: 401
Εγγραφή: 04 Αύγ 2005 14:35
Τοποθεσία: Katerini
Επικοινωνία:

Thread Safety

Δημοσίευση από lakritidis » 20 Φεβ 2009 00:41

Μηπως ξέρεις κανένα freeware utility για thread minitoring και εντοπισμό race conditions σαν to Intel Thread Checker?

Άβαταρ μέλους
soteres2002
S. & H. Moderator
Δημοσιεύσεις: 1524
Εγγραφή: 05 Μαρ 2004 22:17
Τοποθεσία: Ιωάννινα

Thread Safety

Δημοσίευση από soteres2002 » 20 Φεβ 2009 00:46

Λογικά θα σου δουλέψει κανονικά, εφόσον θα σου επιστρέψει έναν valid pointer που φαντάζομαι θα είναι ορατός και στην συνάρτηση του thread, και άρα θα μπορείς να το ορισεις ώς thread specific.

Άβαταρ μέλους
soteres2002
S. & H. Moderator
Δημοσιεύσεις: 1524
Εγγραφή: 05 Μαρ 2004 22:17
Τοποθεσία: Ιωάννινα

Thread Safety

Δημοσίευση από soteres2002 » 20 Φεβ 2009 00:47

lakritidis έγραψε:Μηπως ξέρεις κανένα freeware utility για thread minitoring και εντοπισμό race conditions σαν to Intel Thread Checker?
Το GDB αρκεί για να κάνεις thread tracing, αλλά δεν βρίσκει μόνο του races. Επίσης, και το valgrind παρέχει ανάλογες δυνατότητες.

lakritidis
Δημοσιεύσεις: 401
Εγγραφή: 04 Αύγ 2005 14:35
Τοποθεσία: Katerini
Επικοινωνία:

Thread Safety

Δημοσίευση από lakritidis » 02 Μαρ 2009 21:38

Μετά απο άπειρα segmentation faults βρήκα το έγκλημα: Οι μεταβλητές που αναφέρονται σαν static διατηρούν την τιμή τους μετά το τέλος της συνάρτησης και επομένως δημιουργούν races.

Βγάζουμε λοιπόν το static απο το declaration των μεταβλητών και εξαφσαλίζουμε το thread safety.

PS. Τρομερό εργαλέιο το valgrind.

Απάντηση

Επιστροφή στο “C, C++”

Μέλη σε σύνδεση

Μέλη σε αυτήν τη Δ. Συζήτηση: Δεν υπάρχουν εγγεγραμμένα μέλη και 0 επισκέπτες