• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

wątki w windows, c

0 głosów
290 wizyt
pytanie zadane 10 stycznia 2021 w C i C++ przez komboboost0 Użytkownik (570 p.)

Prosiłbym o wskazanie błędów w poniższym programie.

(1) Struktura którą przekazuję wątkom za każdym razem zawiera te same dane.

(2) Oprócz tego nie rozumiem, dlaczego mój program zawiesza się w połowie działania, jeżeli umieszczę linię zwalniającą pamięć ze wskaźnika threadData na koniec funkcji piSum.

//program oblicza wartosc liczby pi wykorzystujac wzor Leibniza
//wykonuje obliczenia z dokladnoscia n i dzieli zadanie na w watkow

#include <stdlib.h>
#include <stdio.h>
#include <float.h>
#include <string.h>
#include <windows.h>
#include <time.h>
#include <math.h>

double pi = 0;

struct DATA {
	long n;
	long w;
	long zakres;
	long reszta;
};

HANDLE mutex;

DWORD WINAPI piSum(LPVOID threadArg) {
	struct DATA* threadData = (struct DATA*)threadArg;
	long n = threadData->n;
	long w = threadData->w;
	long zakres = threadData->zakres;
	long reszta = threadData->reszta;

	DWORD self = GetCurrentThreadId();

	long first = n * zakres;
	if (n == w-1)
		zakres += reszta;
	double suma = 0;
	
    fprintf(stdout, "thread: %lxd\tsize= %ld\tfirst= %ld\n", self, zakres, first);
	
	for (long index = first ; index <= zakres + first; index++){
		suma = suma + pow(-1, index) / (2 * index + 1);
    }

    fprintf(stdout, "thread: %lxd\tprod= %.20f\n", self, suma);

	WaitForSingleObject(mutex, INFINITE);
	pi = pi + suma;
	ReleaseMutex(mutex);

	free(threadData);  // (2)

	return 0;
}

int main(int argc, char* argv[]){
    fprintf(stdout, "\n");
	long n = atoi(argv[1]);
	long w = atoi(argv[2]);
	int boolFlag = 0;
	if(n <= 1 || n >= 1000000000){
		fprintf(stderr, "n musi spelniac warunek 1<n<1000000000\n");
		boolFlag = 1;
	}

	if(w <= 1 || w >= 100){
		fprintf(stderr, "w musi spelniac warunek 1<w<100\n");
		boolFlag = 1;
	}
	
	if(boolFlag) return 0;
	

	long reszta = n % w;
	long zakres = (n - reszta) / w;
	HANDLE* threads = (HANDLE*)malloc(sizeof(HANDLE) * w);
	DWORD* thrdids = (DWORD*)malloc(sizeof(DWORD) * w);
	mutex = CreateMutex(NULL, FALSE, NULL);

    clock_t t1 = clock();
    struct DATA* args = malloc(sizeof(struct DATA));
	for (int i = 0; i < w; i++){
		args->n = i;   // (1)
		args->w = w;
		args->zakres = zakres;
		args->reszta = reszta;
		threads[i] = CreateThread(NULL, 0, piSum, args, 0, &thrdids[i]);
	}
	for (int i = 0; i < w; i++){
    	WaitForSingleObject(threads[i], INFINITE);
		CloseHandle(threads[i]);
	}
    clock_t t2 = clock();
    double time_s = ((double)t2 - (double)t1) / CLOCKS_PER_SEC;

	printf("\n w/threads pi= %.20f\ttime= %f\n", pi*4, time_s);
    
    pi = 0;
    t1 = clock();
    for (long i = 0; i < n; i++){
        pi += pow(-1, i) / (2*i+1);;
    }
	t2 = clock();
    time_s = ((double)t2 - (double)t1) / CLOCKS_PER_SEC;
	
    printf("wo/threads pi= %.20f\ttime= %f\n\n", pi*4, time_s);

	free(threads);
	free(thrdids);
	free(args);

return 0;

 

1 odpowiedź

+1 głos
odpowiedź 10 stycznia 2021 przez tangarr Mędrzec (155,140 p.)
wybrane 10 stycznia 2021 przez komboboost0
 
Najlepsza
Do wszystkich wątków przekazujesz tą samą strukturę.
Pierwszy wątek, który ukończy zadanie zwalnia tą pamięć.
1
komentarz 10 stycznia 2021 przez j23 Mędrzec (195,220 p.)

W sumie mógłby przekazać tę samą strukturę, tylko musiałby synchronizować dostęp do niej w liniach 24-28 i 81-85. Wtedy free w wątku jest oczywiście zbędne.

pi zrobiłbym volatile.

 

komentarz 10 stycznia 2021 przez tangarr Mędrzec (155,140 p.)
Możesz wyjaśnić dlaczego chciałbyś oznaczyć zmienną pi jako volatile?
komentarz 11 stycznia 2021 przez j23 Mędrzec (195,220 p.)

Nie jestem pewny, czy w tym konkretnym przypadku zmieniłoby to cokolwiek, ale chodzi o to, by kompilator nie stosował agresywnej optymalizacji w stosunku do tej zmiennej. Chociaż w nowszych standardach C i C++ zastosowanie tego specyfikatora nieco ograniczono (C++ ma std::atomic).

Podobne pytania

0 głosów
0 odpowiedzi 832 wizyt
pytanie zadane 18 stycznia 2021 w C i C++ przez MaTiDxxx Początkujący (290 p.)
0 głosów
1 odpowiedź 1,196 wizyt
0 głosów
1 odpowiedź 287 wizyt
pytanie zadane 26 kwietnia 2018 w C i C++ przez Storm Obywatel (1,570 p.)

93,729 zapytań

142,668 odpowiedzi

323,283 komentarzy

63,288 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj

Twierdza Linux. Bezpieczeństwo dla dociekliwych

Aby uzyskać rabat -10%, użyjcie kodu pasja-linux, wpisując go w specjalne pole w koszyku.

...