Aplikacje wielowątkowe

  1. Rozważmy sytuację, gdy aplikacja serwera potrzebuje 30 sekund ciągłych obliczeń do obsługi jednego zapytania od klienta. Pojawia się problem, gdy w tym czasie inne aplikacje klienckie spróbują połączyć się do naszego serwera.

    Przydatnym narzędziem do rozwiązania tego problemu są wątki, które umożliwiają przetwarzanie równoległe wielu zadań. Wątki wykorzystują zdefiniowaną przez nas funkcję/procedurę, która będzie uruchomiona równolegle niezależnie od całości programu, tj. pozwoli naprzetworzenie dwóch lub więcej zadań przez nasz program w taki sposób jak by działały równolegle.
    #include <stdio.h>
    #include <stdlib.h>
    #include <pthread.h>
    
    /* Definicja funkcji, której kod określony jest poniżej */
    
    void *wypisz_wiadomosc( void *ptr );
    
    int main()
    {
    	pthread_t threads[2];
    	const char *wiadomosc1 = "Wątek 1";
    	const char *wiadomosc2 = "Wątek 2";
    	int  tid[2];
    
    	/* Utworzenie dwóch niezależnych wątków, każdy uruchomi funkcję wypisz_wiadomosc */
    
    	tid[0] = pthread_create( &threads[0], NULL, wypisz_wiadomosc, (void*) wiadomosc1);
    	tid[1] = pthread_create( &threads[1], NULL, wypisz_wiadomosc, (void*) wiadomosc2);
    
    	/* Funkcja main musi poczekać na zakończenie obu wątków, po to by nie powstały procesy Zombie */
    
    	pthread_join( threads[0], NULL);
    	pthread_join( threads[1], NULL);
    
    	printf("Wątek 1 zwraca: %d\n",tid[0]);
    	printf("Wątek 2 zwraca: %d\n",tid[1]);
    	exit(0);
    }
    
    void *wypisz_wiadomosc( void *ptr )
    {
    char *message;
    message = (char *) ptr;
    printf("%s \n", message);
    }
    
    Wykorzystanie wielowątkowości z socketami:
    //....
    //
    void *wypisz_wiadomosc(int socket);
    int main(){
    	//....
    	//
    	int socket_client;
    	//....
    	//
    	while(1) {
    		
    		int addrlen=sizeof(struct sockaddr);
    		socket_client = accept(socket_server,(struct sockaddr*)&client_addr,&addrlen);
    		if(socket_client<0) continue;
    		pthread_t pth;
    		pthread_create(&pth,NULL,(void*)wyslij_wiadomosc,(void*) &socket_client);
    	}
    }
    
    void *wyslij_wiadomosc(void* socket_client){
    	char bufor[1024];
    	int socket = *(int*)socket_client;
    	sprintf(bufor,"Hello world.\n");
    	write(socket,bufor,1024);
    }
    
  2. Zadanie 1

    Napisz aplikację serwera, który po połączeniu klienta będzie wypisywał zawartość jakiegoś pliku, przesyłając 10bajtów na sekundę. Serwer po uruchomieniu będzie nasłuchiwał na porcie 10000. Napisz aplikację klienta, która będzie się łączyła z serwerem opisanym powyżej, a po połączeniu będzie odczytywała plik przesyłany przez serwer i zapisywała go w lokalnym katalogu pod losową nazwą.