[C++] biblioteka thread.h


(wojmal) #1

Cześć,

w książce A. S. Tanebauma i H. Bosa pt. "Systemy operacyjne" znalazłem program napisany w C mający za zadanie tworzyć i zaraz niszczyć wątki. Kod ten skompilowałem w Dev-Cpp i działa! Tutaj kod:

#include <cstdlib>

#include <iostream>

#include <cstdio>

#include <pthread.h>

#define NUMBER_OF_THREADS 10



using namespace std;



void *phw(void *tid)

{

	printf("Thread no.: %d\n", tid);

	pthread_exit(NULL);	

}



int main()

{

	pthread_t thr[NUMBER_OF_THREADS];

	int status, i;

	

	for (i=0; i<NUMBER_OF_THREADS; i++)

	{

		printf("Hello World %d\n", i);

		status = pthread_create(&thr[i], NULL, phw, &i);

	}

}

Wynik działania jest jednak bardzo dziwny, dwa łańcuchy z funkcji printf() nakładają się na siebie i wszystko staje się nieczytelne (zrzut ekranu w załączniku). Dlaczego tak się dzieje i jak to poprawić. Z góry dziękuję za pomoc.

Przechwytywanie.PNG


(stasinek) #2

Jakiej wersji uzywasz? To zalezy od printf w MinGW widocznie Twoja wersja jest wadliwa.

 Skompilowalem w nowszym Dev++ 5.11 https://sourceforge.net/projects/orwelldevcpp/ i jest ok :wink:


(wojmal) #3

Używam Dev-C++ w wersji 5.11. Inne programy z wykorzystaniem printf() zachowują się normalnie.


(Fizyda) #4

Prawdopodobnie dzieje się tak bo robisz to w wątkach wykonywanych w tym samym czasie (prawie), więc to tak może wyglądać. Uruchom program kilka razy i idę o zakład że otrzymasz różne wyniki w konsoli bo zależy to od aktualnej sytuacji w systemie, ile czasu procesora dostanie każdy wątek, algorytmu wywłaszczania. Przed wyświetleniem napisu uśpij wątek na tid sekund w tedy będą Ci się wyświetlały co sekundę.

Ewentualnie w pętli przed wyświetleniem napisu wykonaj jakieś obliczenia w pętli losową ilość razy dla poszczególnych wątków. W tedy nawet w różnej kolejności będą Ci się wyświetlały napisy z poszczególnych wątków.

 

Kwestią tego czemu się tak dzieje jest prawdopodobnie użyty przez Ciebie kompilator, ewentualnie jakieś opcje kompilacji.


(stasinek) #5

 

printf w mingw-64 nie jest thread safe więc w tdm też nie, może wersja 32 bit jest inna dlatego u mnie ok… 

https://sourceforge.net/p/mingw-w64/discussion/723797/thread/55520785/

myślałem że printf jest bezpieczne…

int sync_printf(const char *format, ...)



{



    va_list args;



    va_start(args, format);







    pthread_mutex_lock(&printf_mutex);



    vprintf(format, args);



    pthread_mutex_unlock(&printf_mutex);







    va_end(args);



}







http://stackoverflow.com/questions/23586682/how-to-use-printf-in-multiple-threads

 


(wojmal) #6

Zgadza się, za każdym razem wynik jest trochę inny. Teraz sobie przysiadłem i dopisałem:

//Program to zmodyfikowana wersja listingu

//pochodzącego z książki A.Tanenbaum i H. Bos

//p.t. "Systemy operacyjne" s. 130n.

#include <cstdlib>

#include <iostream>

#include <cstdio>

#include <pthread.h>

#include <time.h>

#define NUMBER_OF_THREADS 10

using namespace std;

void czekaj(int sek) // dopisane teraz

{

	int teraz=time(NULL);

	while(time(NULL)<teraz+sek)

	{

	}

}



void *phw(void *tid)

{

	czekaj(2); // dopisane teraz

	printf("Thread no.: %d\n", tid);

	pthread_exit(NULL);	

}

int main()

{

	pthread_t thr[NUMBER_OF_THREADS];

	int status, i;

	for (i=0; i<NUMBER_OF_THREADS; i++)

	{

		printf("Hello World %d\n", i);

		status = pthread_create(&thr[i], NULL, phw, (void*)i);

		czekaj(4); //dopisane teraz

	}

	system("PAUSE");

}

Teraz jest OK. Czy te błędy mogą wynikać ze specyfikacji procesora (Intel i5) i/lub systemu (Windows 10)? Listing z książki zakładał chyba, że wątek główny będzie czekał aż wykona się procedura z nowego wątku. Idę szukać dalej.
Nie znalazłem nigdzie opcji w Dev-C++ do zmiany sposobu wykonywania wątków.