Интервал времени в потоке - PullRequest
0 голосов
/ 09 ноября 2010

Мне нужно смоделировать игру в рулетку для упражнения (без оценки), которое дал нам наш лектор. Это должно быть многопоточное клиент-серверное приложение. Я проектирую сервер (клиент довольно прост, ему нужно только отправить запросы ставки), но я застрял. У меня есть две функции потока, крупье: это вытащить числа каждые N секунд (указано в командной строке) игрок: этот читает число, вытащенное крупье и вставляет ставки в общий список. Каждый игрок может сделать ставку один или несколько раз.

Моя проблема: могу ли я использовать cond_timedwait для имитации временного интервала между двумя вытягиваемыми числами? Есть ли другой способ сделать это?

void *croupier(void *arg) {
struct timespec cond_time; 
time_t now; 
int status;
int intervallo = (int) arg;

//initializerand seed
srand(time(NULL));

while (1) {
    //lock mutex for number extraction
    status = pthread_mutex_lock(&puntate_mutex);
    if (status != 0) {
        err_abort(status, "Lock sul mutex nel croupier");
    }
    //number extraction
    estratto = rand() % 37;

    printf("CROUPIER estratto=%d\n", estratto);
    /* wake up players */
    status = pthread_cond_broadcast(&puntate_cond);
    if (status != 0) {
        err_abort(status, "Broadcast condition in croupier");
    }

    now = time(NULL);
    cond_time.tv_sec = now + intervallo;
    cond_time.tv_nsec = 0;
    //wait for condition
    while (estratto > 0) {
        status = pthread_cond_timedwait(&croupier_cond, &puntate_mutex, &cond_time);
        //if status == ETIMEDOUT, time is over
        if (status == ETIMEDOUT) {
            printf("CROUPIER time's over!!! Bets closed\n");
            estratto = -1; //bets closed
            break;
        }
        if (status != 0) {
            err_abort(status, "Timedwait croupier");
        }
    }

    printf("CROUPIER Gestisco la puntata\n");
    //TODO manage bets
    status = pthread_mutex_unlock(&puntate_mutex);
    if (status != 0) {
        err_abort(status, "Unlock sul mutex nel player");
    }
}
pthread_exit(NULL);
 }

void *player(void *arg) {
int num = (int) arg;
int letto = 0;
int status;

while (1) {
    status = pthread_mutex_lock(&puntate_mutex);
    if (status != 0) {
        err_abort(status, "Lock sul mutex nel player");
    }

    /* (estratto < 0) means that bets are closed */
    while (estratto < 0) {/* if bets are closed */
        printf("GIOCATORE %d CONDIZIONE FALSA\n", num);
        letto = 0;
        pthread_cond_wait(&puntate_cond, &puntate_mutex); //TODO inserire gestione errori
    }

    //here player can bet
    /*???????
     * read bet on socket
     * insert bet in list
     * */

    status = pthread_mutex_unlock(&puntate_mutex);
    if (status != 0) {
        err_abort(status, "Unlock sul mutex nel player");
    }
}
pthread_exit(NULL);
}

1 Ответ

0 голосов
/ 10 ноября 2010

Вероятно, было бы проще просто использовать sleep () или usleep (), чтобы приостановить поток на необходимый интервал.


Обновление:

Просто разблокируйте мьютекс перед сном и снова заблокируйте его, когда вы просыпаетесь.

Думайте о мьютексе как о защите доступа к estratto - вы хотите заблокировать мьютекс только до тех пор, пока вы изменяете / считываете это общее значение. Итак:

lock()
estratto = rand() % 37;
unlock()

В частности, обратите внимание, что:

  • вы обычно не хотите выполнять терминальный ввод-вывод (printf), удерживая мьютекс (если этот ввод-вывод заблокирован из-за управления сетевым потоком, любые другие потоки, которым необходим мьютекс, тоже будут заблокированы)

  • вам не нужно блокировать мьютекс, чтобы сделать pthread_cond_broadcast

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...