Przetwarzanie współbieżne
Wojciech Kupczyk Data
Laboratorium 3
94415 13.03.2014, 14:30
Cele laboratorium:
�� atrybuty wątków PTHREADS.
Zrealizowane zadania: 1-6
Ad. 2. Uruchomienie na dziesięciu wątkach funkcji wyświetlającej identyfikator wątku.
Program wyświetla kolejny numer (argument przekazany do wątku) oraz dodatkowo
TID identyfikator wątku.
#include
#include
#include
#include
void * zadanie_watku (void * arg_wsk);
main(){
int i,tablica_wyn[10];
pthread_t tablica_tid[10];
for(i=0; i<10; i++){
tablica_wyn[i] = pthread_create(&tablica_tid[i], NULL, zadanie_watku, &i);
tablica_wyn[i] = pthread_join(tablica_tid[i], NULL);
}
}
void * zadanie_watku (void * arg_wsk)
{
int moj_arg;
pid_t tid = (pid_t) syscall (SYS_gettid);
moj_arg = *( (int *) arg_wsk );
printf("Watek otrzymal argument %d. TID: %u\n",moj_arg,
tid);
sleep(1);
return(NULL);
}
Ad. 3. Załączony program watki.c został przeanalizowany i uzupełniony, zgodnie ze
wskazówkami ze skryptu. Uzupełniony kod funkcji main przedstawiony jest na
poniższym listingu, a poniżej zrzut ekranu z jego wykonania. Żółtym zakreśleniem
zostały zaznaczone dodane fragmenty kodu.
int main()
{
pthread_t tid;
pthread_attr_t attr;
void *wynik;
int i;
//Wątek przyłączalny
printf("watek glowny: tworzenie watku potomnego nr 1\n");
/*Tu wstaw kod tworzenia wątku z domyślnymi własnościami*/
pthread_create(&tid, NULL, zadanie_watku, NULL);
sleep(2); // czas na uruchomienie watku
printf("\twatek glowny: wyslanie sygnalu zabicia watku\n");
pthread_cancel(tid);
pthread_join(tid, &wynik);
//Co nalezy zrobić przed sprawdzeniem czy wątki się skonczyły?
//Przed sprawdzeniem należy wywołać pthread_join zapisując wynik wywołania w zmiennej wynik
if (wynik == PTHREAD_CANCELED)
printf("\twatek glowny: watek potomny zostal zabity\n");
else
printf("\twatek glowny: watek potomny NIE zostal zabity - blad\n");
//Odłączanie wątku
zmienna_wspolna = 0;
printf("watek glowny: tworzenie watku potomnego nr 2\n");
/*Tu wstaw kod tworzenia wątku z domyślnymi własnościami*/
pthread_create(&tid, NULL, zadanie_watku, NULL);
sleep(2); // czas na uruchomienie watku
printf("\twatek glowny: odlaczenie watku potomnego\n");
//Instrukcja odłączenia?
pthread_detach(tid);
printf("\twatek glowny: wyslanie sygnalu zabicia watku odlaczonego\n");
pthread_cancel(tid);
//Czy watek został zabity? Jak to sprawdzić?
printf("\twatek glowny: czy watek potomny zostal zabity \n");
printf("\twatek glowny: sprawdzanie wartosci zmiennej wspolnej\n");
for(i=0; i<10; i++)
{
sleep(1);
if(zmienna_wspolna!=0) break;
}
if (zmienna_wspolna == 0)
printf("\twatek glowny: odlaczony watek potomny PRAWDOPODOBNIE zostal zabity\n");
else
printf("\twatek glowny: odlaczony watek potomny PRAWDOPODOBNIE NIE zostal zabity\n");
//Wątek odłączony
//Inicjacja atrybutów?
pthread_attr_init(&attr);
//Ustawianie typu watku na odłaczony
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
printf("watek glowny: tworzenie odlaczonego watku potomnego nr 3\n");
pthread_create(&tid, &attr, zadanie_watku, NULL);
//Niszczenie atrybutów
pthread_attr_destroy(&attr);
printf("\twatek glowny: koniec pracy, watek odlaczony pracuje dalej\n");
//pthread_exit(NULL); // co stanie sie gdy uzyjemy exit(0)?
exit(0);
}
Ad. 4. Na podstawie poprzedniego punktu stworzyłem program, który uruchamia funkcję
czasozajmowacz na 8 wątkach i przetestowałem działanie funkcji
pthread_attr_setstacksize oraz pthread_setaffinity_np. Poniżej załączam
fragmenty kodu, w których wykorzystywane są powyższe funkcje.
pthread_attr_setstacksize:
errno = pthread_attr_init(&attr);
if (errno) {
perror("pthread_attr_init");
return EXIT_FAILURE;
}
if (argc > 1) {
rozmiar = atoi(argv[1]);
printf("rozmiar stosu ustalony przez użytkownika: %u\n", rozmiar);
printf("minimalny rozmiar stosu: %u\n", PTHREAD_STACK_MIN);
errno = pthread_attr_setstacksize(&attr, rozmiar);
test_errno("pthread_attr_setstacksize");
}
else {
pthread_attr_getstacksize(&attr, &rozmiar);
printf("domyślny rozmiar stosu: %u\n", rozmiar);
}
for(i=0; i<8; i++){
printf("watek glowny: tworzenie watku potomnego nr %d\n",i);
errno = pthread_create(&tablica_tid[i], &attr, zadanie_watku, &i);
test_errno("pthread_create");
pthread_join(tablica_tid[i], NULL);
sleep(1); // czas na uruchomienie watku
}
pthread_setaffinity_np:
thread = pthread_self();
/* Set affinity mask to include CPUs 0 to 7 */
CPU_ZERO(&cpuset);
for (j = 0; j < 8; j++)
CPU_SET(j, &cpuset);
s = pthread_setaffinity_np(thread, sizeof(cpu_set_t), &cpuset);
if (s != 0)
handle_error_en(s, "pthread_setaffinity_np");
/* Check the actual affinity mask assigned to the thread */
s = pthread_getaffinity_np(thread, sizeof(cpu_set_t), &cpuset);
if (s != 0)
handle_error_en(s, "pthread_getaffinity_np");
printf("Set returned by pthread_getaffinity_np() contained:\n");
for (j = 0; j < CPU_SETSIZE; j++)
if (CPU_ISSET(j, &cpuset))
printf(" CPU %d\n", j);
Właściwości pthread_setschedparam zostały omówione poniżej. Podana funkcja służy do
modyfikowania priorytetu wątku. Jednym z jej argumentów jest wskaznik na strukturę typu
sched_param, której pole sched_priority określa priorytet wątku. Elementy struktury
sched_param zostały przedstawione w poniższej tabeli.
sched_priority
Priorytet normalny N na którym ma być wykonywany dany wątek.
Priorytet obniżony L. Będzie on ustawiony przez system gdy wątek
sched_ss_low_priority
wyczerpie swój aktualny budżet C.
sched_ss_max_repl
Maksymalna liczba zdarzeń odnawiających.
Okres T po którym budżet wątku zostanie odnowiony do wielkości
sched_ss_repl_period
budżetu początkowego C.
Ilość czasu przez którą wątek może wykonywać się na normalnym
sched_ss_init_budget
priorytecie zanim priorytet jego obniży się do L.
Ad. 5. Poniżej zamieszczam screen konsoli (htop) wykonany podczas działania programu z
zadania 4 (czwarte_1).
Ad. 6. Nowy program, w którym zostało stworzone 10 wątków. Każdy wątek otrzymał
losowe wartości atrybutów, które następnie zostały wyświetlone w procedurze wątku.
Kod zródłowy całej aplikacji i przykładowy wydruk pokazujący wynik działania
programu załączam poniżej.
void * zadanie_watku (void * arg_wsk)
{
pthread_attr_t attr;
pthread_getattr_np(pthread_self(), &attr);
int k;
size_t stack_size, guard_size;
void *stack_addr;
pthread_attr_getdetachstate(&attr, &k);
printf("Detach state = %d\n", k);
pthread_attr_setinheritsched(&attr, k);
printf("Inherit sched = %d\n", k);
pthread_attr_getguardsize(&attr, &guard_size);
printf("Guard size = %d bytes\n", guard_size);
pthread_attr_getstack(&attr, &stack_addr, &stack_size);
printf("Stack address = %p\n\n", stack_addr);
pthread_self(void);
pthread_attr_destroy(&attr);
return(NULL);
}
int main()
{
pthread_t tid[10];
pthread_attr_t attr;
void *wynik;
int i, los;
srand(time(0));
for(i = 0; i<10; i++)
{
pthread_attr_init(&attr);
srand(time(0));
los = rand()%2;
pthread_attr_setdetachstate(&attr, los);
srand(time(0));
los = rand()%2;
pthread_attr_setinheritsched(&attr, los);
pthread_create(&tid[i], &attr, zadanie_watku,
NULL);
pthread_attr_destroy(&attr);
sleep(1);
}
pthread_exit(NULL);
}
Wyszukiwarka
Podobne podstrony:
33B Skrzypek Mateusz LAB 5
33B Skrzypek Mateusz LAB 3 5
Lab BD Wojciech Ćwikliński
Lab cpp
lab 2
T2 Skrypt do lab OU Rozdział 6 Wiercenie 3
IE RS lab 9 overview
lab pkm 3
lab chemia korozja
lab tsp 3
MICHAŁ WOJCIECHOWSKI ZASADY SPOŁECZNE STAREGO TESTAMENTU
Lab
więcej podobnych podstron