• 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

VPS Starter Arubacloud
+1 głos
492 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ź 233 wizyt
0 głosów
1 odpowiedź 503 wizyt

92,455 zapytań

141,263 odpowiedzi

319,100 komentarzy

61,854 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

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 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!

...