LINUX.ORG.RU

Потоки

 ,


0

1

Задача такая: В колоде(52 карты), рассчитать экспериментально (метод Монте-Карло) вероятность того, что сверху лежат две одинаковых карты. Количество раундов подается с ключом.

Создаю поток, в котором вызываю функцию generator, но она не выводит на экран 2 случайные карты. В чем может быть проблема?

#include <assert.h>
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <pthread.h>

#define ARRAY_SIZE(a) (sizeof (a) / sizeof *(a))
#define COMPARE(a, b) (((a) > (b)) - ((a) < (b)))
const char RANKS[] = "23456789TJQKA";
const char SUITS[] = "SHDC"; /* Spades, Hearts, Diamonds, Clubs */
#define N_RANKS (13)
#define N_SUITS (4)
#define ERROR_CREATE_THREAD -11
#define ERROR_JOIN_THREAD   -12
#define SUCCESS        0

typedef struct Card{
  unsigned suit, rank;
} Card;
 
typedef Card Cards[52];
 
void init_cards(Cards *cards){
 assert(cards != NULL);
 
 Card *card = *cards;
 unsigned suit;
 unsigned rank;
  for (suit = 0; suit < N_SUITS; ++suit)
    for (rank = 0; rank < N_RANKS; ++rank)
    {
      card->suit = suit;
      card->rank = rank;
      ++card;
    }
 
  assert(card == *cards + ARRAY_SIZE(*cards));
}
 
void shuffle_cards(Cards *cards, unsigned limit_size){
  assert(cards != NULL);
  assert(limit_size <= ARRAY_SIZE(*cards));
 
 unsigned i;
  for (i = 0; i < limit_size; ++i)
  {
    unsigned j = rand() % (ARRAY_SIZE(*cards) - i) + i;
    Card temp = (*cards)[i];
    (*cards)[i] = (*cards)[j];
    (*cards)[j] = temp;
  }
}

void print_cards(const Card cards[], unsigned n){
    const Card *card;
    const Card *card_end = cards + n;
      for (card = cards; card != card_end; ++card)
        printf("%c%c ", SUITS[card->suit], RANKS[card->rank]);
 
      printf("\n");
}

/*int compare_cards(const Card cards[], unsigned n)
{
}*/


void* generator(void *args){
srand((unsigned) time(NULL));
Cards cards;
init_cards(&cards);
shuffle_cards(&cards, 2);
Card *player = cards;
print_cards(player, 2);
}
 


int main(int argc, char* argv[]){
int q,i,size,result;
pthread_t thread;
	if (argc < 2){
		printf("Please enter int\n");
		return 1;
	}
	q=atoi(argv[2]);
	printf("Q=%d\n",q);

	result = pthread_create(&thread, NULL, generator, NULL);
   	if (result != 0) {
     		printf("main error: can't create thread, status = %d\n", result);
        	exit(ERROR_CREATE_THREAD);
	}
	
}

Готово, теперь проблема в том, как создать q потоков, которые будут генерировать случайные карты написал так, но работает только для одиночного случая

#include <assert.h>
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <pthread.h>

#define ARRAY_SIZE(a) (sizeof (a) / sizeof *(a))
#define COMPARE(a, b) (((a) > (b)) - ((a) < (b)))
const char RANKS[] = "23456789TJQKA";
const char SUITS[] = "SHDC"; /* Spades, Hearts, Diamonds, Clubs */
#define N_RANKS (13)
#define N_SUITS (4)
#define ERROR_CREATE_THREAD -11
#define ERROR_JOIN_THREAD   -12
#define SUCCESS        0
typedef struct Card{
  unsigned suit, rank;
} Card;
 
typedef Card Cards[52];
 
void init_cards(Cards *cards){
 assert(cards != NULL);
 
 Card *card = *cards;
 unsigned suit;
 unsigned rank;
  for (suit = 0; suit < N_SUITS; ++suit)
    for (rank = 0; rank < N_RANKS; ++rank)
    {
      card->suit = suit;
      card->rank = rank;
      ++card;
    }
 
  assert(card == *cards + ARRAY_SIZE(*cards));
}
 
void shuffle_cards(Cards *cards, unsigned limit_size){
  assert(cards != NULL);
  assert(limit_size <= ARRAY_SIZE(*cards));
 
 unsigned i;
  for (i = 0; i < limit_size; ++i)
  {
    unsigned j = rand() % (ARRAY_SIZE(*cards) - i) + i;
    Card temp = (*cards)[i];
    (*cards)[i] = (*cards)[j];
    (*cards)[j] = temp;
  }
}

void print_cards(const Card cards[], unsigned n){
    const Card *card;
    const Card *card_end = cards + n;
      for (card = cards; card != card_end; ++card)
        printf("%c%c ", SUITS[card->suit], RANKS[card->rank]);
 
      printf("\n");
}

/*int compare_cards(const Card cards[], unsigned n)
{
}*/


void* generator(void *args){
srand((unsigned) time(NULL));
Cards cards;
init_cards(&cards);
shuffle_cards(&cards, 2);
Card *player = cards;
print_cards(player, 2);
}

void* helloWorld(void *args) {
    printf("Hello from thread!\n");
    return SUCCESS;
}
 
int main(int argc, char* argv[]){
   
    int q,i;

	if (argc < 2){
		printf("Please enter int\n");
		return 1;
	}
	q=atoi(argv[2]);
	printf("Q=%d\n",q);
    
    for(i=1;i<q;i++){
    pthread_t thread;
    int status,size,result;
    int status_addr;    

    status = pthread_create(&thread, NULL, generator, NULL);
    if (status != 0) {
        printf("main error: can't create thread, status = %d\n", status);
        exit(ERROR_CREATE_THREAD);
    }
    printf("Hello from main!\n");
 
    status = pthread_join(thread, (void**)&status_addr);
    if (status != SUCCESS) {
        printf("main error: can't join thread, status = %d\n", status);
        exit(ERROR_JOIN_THREAD);
    }
 
    printf("joined with address %d\n", status_addr);
    return 0;
}
}
timas-cs
() автор топика
Ответ на: комментарий от timas-cs

но работает только для одиночного случая

for(i=1;i<q;i++) {
  pthread_create()
  ...
  pthread_join()
}


Собственно, а что ты хотел ? Ты создал поток, и сразу же ждешь его завершения (join()), конечно, оно будет однопоточное :)

joy4eg ★★★★★
()
Ответ на: комментарий от joy4eg

Вроде работает не очень хорошо

#include <assert.h>
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <pthread.h>

#define ARRAY_SIZE(a) (sizeof (a) / sizeof *(a))
#define COMPARE(a, b) (((a) > (b)) - ((a) < (b)))
const char RANKS[] = "23456789TJQKA";
const char SUITS[] = "SHDC"; /* Spades, Hearts, Diamonds, Clubs */
#define N_RANKS (13)
#define N_SUITS (4)
#define ERROR_CREATE_THREAD -11
#define ERROR_JOIN_THREAD   -12
#define BAD_MESSAGE         -13
#define SUCCESS        0

typedef struct Card{
  unsigned suit, rank;
} Card;
 
typedef Card Cards[52];
 
void init_cards(Cards *cards){
 assert(cards != NULL);
 
 Card *card = *cards;
 unsigned suit;
 unsigned rank;
  for (suit = 0; suit < N_SUITS; ++suit)
    for (rank = 0; rank < N_RANKS; ++rank)
    {
      card->suit = suit;
      card->rank = rank;
      ++card;
    }
 
  assert(card == *cards + ARRAY_SIZE(*cards));
}
 
void shuffle_cards(Cards *cards, unsigned limit_size){
  assert(cards != NULL);
  assert(limit_size <= ARRAY_SIZE(*cards));
 
 unsigned i;
  for (i = 0; i < limit_size; ++i)
  {
    unsigned j = rand() % (ARRAY_SIZE(*cards) - i) + i;
    Card temp = (*cards)[i];
    (*cards)[i] = (*cards)[j];
    (*cards)[j] = temp;
  }
}

void print_cards(const Card cards[], unsigned n){
    const Card *card;
    const Card *card_end = cards + n;
      for (card = cards; card != card_end; ++card)
        printf("%c%c ", SUITS[card->suit], RANKS[card->rank]);
 
      printf("\n");
}

/*int compare_cards(const Card cards[], unsigned n)
{
}*/


void* generator(void *args){
srand((unsigned) time(NULL));
Cards cards;
init_cards(&cards);
shuffle_cards(&cards, 2);
Card *player = cards;
print_cards(player, 2);
}

int main(int argc, char* argv[]){
   
    int q;

	if (argc < 2){
		printf("Please enter int\n");
		return 1;
	}
	q=atoi(argv[2]);
	printf("Q=%d\n",q);
    
    pthread_t threads[q];
    int status;
    int i;
    int status_addr;

    for (i = 0; i < q; i++) {
        status = pthread_create(&threads[i], NULL, generator, NULL);
        if (status != 0) {
            printf("main error: can't create thread, status = %d\n", status);
            exit(ERROR_CREATE_THREAD);
        }
    }
    
    printf("Main Message\n");
 
    for (i = 0; i < q; i++) {
        status = pthread_join(threads[i], (void**)&status_addr);
        if (status != SUCCESS) {
            printf("main error: can't join thread, status = %d\n", status);
            exit(ERROR_JOIN_THREAD);
        }
        printf("joined with address %d\n", status_addr);
    }

    return 0;
}

timas-cs
() автор топика
Ответ на: комментарий от timas-cs

А какой смысл это в 100500 потоков делать?

И зачем выводить все варианты, если можно было бы просто суммировать количество попыток fail / success?

anonymous
()
Ответ на: комментарий от timas-cs

Дальше код не смотрел. Потоки работают ? Да. Значит, решено :))

joy4eg ★★★★★
()

Про потоки: так и должно быть. Новый опыт = новый поток. И последний вопрос. В n потоках создается по 1 переменной, равной 0 или 1(удача или неудача опыта), как проссумировать их?

timas-cs
() автор топика
Ответ на: комментарий от timas-cs

Читай про мьютексы.

И не забывай, что любая синхронизация — это торможение. Если у тебя запущено 100500 потоков, то все будут ждать самого тормоза. Поэтому все, требующее синхронизации, надо как можно аккуратней делать.

Идеальный вариант - вообще каждым потоком писать в свою ячейку массива, а как все завершатся, просуммировать содержимое массива.

anonymous
()
Ответ на: комментарий от anonymous

Спасибо большое за помощь! Разобрался и все написал!

timas-cs
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.