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

Takie same liczby losowe, Programowanie współbieżne

Object Storage Arubacloud
+1 głos
534 wizyt
pytanie zadane 21 października 2021 w C i C++ przez cba Użytkownik (620 p.)

Witam, mam oto taki kod:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
#include <time.h>

#define MAXL 10

int l_losowe [MAXL];
long licznik = 0;

void* p(void* l)
{
	srand(time(NULL));
	long n = (long)l;
	
	int los = rand()%10;
	
	l_losowe[n]=los;
	
	printf("watek nr %ld, liczba %d\n",n,los);
	return 0;
}
int main()
{
	
	pthread_t w[MAXL];
	for(licznik = 0;licznik<MAXL;licznik++)
	{
		pthread_create(&w,0,p,(void*)licznik);
	}
	for(licznik = 0;licznik<MAXL;licznik++)
	{
		pthread_join(w[licznik],0);
	}
	
	int j=0,x=0;
	for(j;j<MAXL;j++)
	{
		x+=l_losowe[j];
	}
	x=x/licznik;
	printf("średnia: %d",x);
	
	return 0;
}

Wypisuje on caly czas ta sama liczbę wylosowaną. Co mogę dodać/przestawić by się tak nie działo?

 

1 odpowiedź

+3 głosów
odpowiedź 21 października 2021 przez mokrowski Mędrzec (155,460 p.)
Linijka 14, powinna znaleźć się w linii 26. Zasiew generatora robi się raz.
komentarz 21 października 2021 przez cba Użytkownik (620 p.)
Niestety to nic nie zmienia, wręcz w ogóle nie losuje liczb tylko zawsze jest 1
komentarz 21 października 2021 przez mokrowski Mędrzec (155,460 p.)

Proponuję byś napisał program z 1 wątkiem i wywołał go szybko 2 razy. Szybko to znaczy poniżej 1 sek. Będziesz miał taką samą wartość.

Następnie wywołaj manual do rand.

man 3 rand

Tam przeczytasz:

The  function  rand()  is  not reentrant, since it uses hidden state that is modified on each call.  This might just be the seed
         value to be used by the next call, or it might be something more elaborate.  In order to get reproducible behavior in a threaded
         application, this state must be made explicit; this can be done using the reentrant function rand_r().

 

komentarz 21 października 2021 przez cba Użytkownik (620 p.)
Okej rozumiem problem ale nie bardzo wiem w jaki sposób mam użyć tej funkcji rand_r(), co dać jako argument.
komentarz 21 października 2021 przez mokrowski Mędrzec (155,460 p.)
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
#include <time.h>
 
#define MAXL 10
 
int l_losowe [MAXL];
long licznik = 0;
unsigned seed = 0;
 
void * p(void * l)
{
    long n = (long)l;
     
    int los = rand_r(&seed)%10;
     
    l_losowe[n] = los;
     
    printf("watek nr %ld, liczba %d\n", n, los);
    return 0;
}

int main(void)
{
    seed = time(NULL);
     
    pthread_t w[MAXL];
    for(licznik = 0; licznik < MAXL; ++licznik)
    {
        pthread_create(&w[licznik], 0, p, (void*)licznik);
    }
    for(licznik = 0; licznik<MAXL ; ++licznik)
    {
        pthread_join(w[licznik], 0);
    }
     
    int j = 0;
    int x = 0;
    for(; j < MAXL; ++j)
    {
        x += l_losowe[j];
    }
    x = x/licznik;
    printf("średnia: %d\n", x);
     
    return 0;
}

 

komentarz 21 października 2021 przez Oscar Nałogowiec (29,290 p.)
Nie wiem, czy sensem rand_r jest używanie jej wielowątkowo na jednej zmiennej globalnej. Albo dajemy oddzielny seed dla każdego wątku - albo jedziemy na zmiennej globalnej (wystarczy wtedy rand), ale wtedy każde wywołanie rand musi być zabezpieczone muteksem.
komentarz 21 października 2021 przez mokrowski Mędrzec (155,460 p.)
Ha, akurat dla rand_r() IMHO pożądane są odczyty fantomowe :) Oczywiście dla innych przypadków bym tego nie sugerował. A globalna bo i przykład mały i trywialny. Ładniej było by zrobić strukturę przesyłaną do wątku, ale tu pewnie była by uwaga że "wykładowca kazał tak a nie inaczej".

Jeszcze lepiej je zrobić thread_local, ale tu znów.. raczej nowszy standard języka.

Podobne pytania

0 głosów
1 odpowiedź 241 wizyt
0 głosów
1 odpowiedź 507 wizyt

92,555 zapytań

141,403 odpowiedzi

319,557 komentarzy

61,940 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.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...