简体   繁体   English

在C中为pthread使用Mutex锁定/解锁和广播

[英]Using Mutex Lock/Unlock and Broadcast for pthreads in C

This is my first post and I'm excited. 这是我的第一篇文章,我很兴奋。

My problem is that I am creating a Rock, Paper, Scissors program in C where the parent process creates 2 threads. 我的问题是我在C中创建了一个Rock,Paper,Scissors程序,其中父进程创建了2个线程。 The 2 threads then throw a random rock, paper, or scissors and return the value to the parent where it gets counted and spits back the results of 3 rounds, then makes a final tally. 然后,这2个线程会随机扔石头,纸或剪刀,并将该值返回给父对象,并在其中对其计数并吐出3个回合的结果,然后进行最后的计数。

My problem is that I cannot get the threads to initiate correctly, I have them waiting in my thread_function1 but then they only complete one round and even then I don't get two threads back in the results. 我的问题是我无法正确启动线程,我在thread_function1中等待它们,但是它们仅完成了一轮,即使那样我也没有得到两个线程。 If someone could please shed some light I would really appreciate it! 如果有人可以请大家说明一下,我将不胜感激! Thanks 谢谢

#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <pthread.h>
#include <sys/time.h>

#define NTHREADS 2
struct timeval tv;
void *thread_function1();
void *thread_function2();
char *guess_string(int g);
int wins[3];
int cmd_ready = 0;
int x1=0, x2=1, count=0;
int  guess, object, turns, i, j, k,l, winner, cmd, go, y;
pthread_mutex_t cv_m;
pthread_mutex_t count_mutex;
pthread_cond_t cv;
int myindex;
int flag; 
int throws[3];
int main(int argc, char *argv[])
{


  wins[0] = 0; wins[1] = 0;
  if ((argc != 2) || ((turns = atoi(argv[1])) <= 0))
    {
      fprintf(stderr,"Usage: %s turns\n", argv[0]);
      return 0;
    }

    pthread_t thread_id1, thread_id2;


    if (pthread_create(&thread_id1, NULL, thread_function1,&x1) != 0)
        perror("pthread_create"),
        exit(1); 

    if (pthread_create(&thread_id2, NULL, thread_function1,&x2) != 0)
        perror("pthread_create"),
        exit(1); 

    printf("Beginning %d Rounds...\nFight!\n", turns);
    printf("Child 1 TID: %d\n", (unsigned int) thread_id1);
    printf("Child 2 TID: %d\n", (unsigned int) thread_id2 );

    for(k=0; k<turns; k++)
    {

            pthread_mutex_lock (&cv_m);
            cmd = go; 
            cmd_ready = 2;
            pthread_cond_broadcast(&cv);    
            pthread_mutex_unlock(&cv_m);
            printf("------------------------\n");
            printf("Round: %d\n", k+1);

            printf("Child %d throws %s!\n",myindex+1, guess_string(myindex));

            pthread_mutex_lock (&count_mutex);

            winner = find_winner(throws[0], throws[1]);
            while(count == 2){
            if(winner >= 0)
            {
                printf("Child %d Wins!\n", winner+1);
                wins[winner]++;
                printf("6\n");
            }else
            {
                printf("Game is a Tie!\n");
            }
            go--;
            count = 0; 
            pthread_mutex_unlock(&count_mutex);
            }
    }

    pthread_join(thread_id1,NULL); 
    pthread_join(thread_id2,NULL);

    printf("------------------------\n");
    printf("------------------------\n");
    printf("Result:\n");
    printf("Child 1: %d\n", wins[0]);
    printf("Child 2: %d\n", wins[1]);
    printf("Ties: %d\n", turns - (wins[0] + wins[1]));
    printf("Child %d Wins!\n", (wins[0] > wins[1]) ? 1 : 2);

    pthread_mutex_destroy(&cv_m);
    pthread_cond_destroy(&cv);
    pthread_exit(NULL);
    return 0; 

}

void *thread_function1(void *p)
{
    struct timeval tv;
    myindex = *(int *)p;
    gettimeofday(&tv, NULL);
    srand(tv.tv_sec + tv.tv_usec + getpid());
    printf("1\n");
    pthread_mutex_lock (&cv_m);
    while(cmd_ready == 0)
    {
        printf("2\n");
        pthread_cond_wait(&cv, &cv_m);
    }
    printf("3\n");

    throws[myindex] = rand() % 3;
    cmd_ready--;
    printf("Ready: %d\n",cmd_ready);
    pthread_mutex_unlock (&cv_m);
    printf("4\n");

    pthread_mutex_lock (&count_mutex);
    count++;
    printf("Count %d\n", count);
    pthread_mutex_unlock(&count_mutex);

    while(count == 2){
        printf("5\n");
        return NULL;
    }

}

char *guess_string(int g){
    switch(g){
    case 0:
        return "Rock";
        break;
    case 1:
        return "Paper";
        break;
    case 2:
        return "Scissors";
        break;
    }
}

int find_winner(int g1, int g2){
    if(g1 == g2)
        return -1; 
    else if ((g1 == 2) && (g2 == 0))
        return 1; 
    else if ((g1 == 0) && (g2 == 2))
        return 0;
    else
        return (g1 > g2) ? 0 : 1;
}

You don't appear to be initializing your mutex or condition with pthread_mutex_init or pthread_cond_init . 您似乎没有使用pthread_mutex_initpthread_cond_init初始化互斥量或条件。

The variable myindex is being modified by both threads without protection, the second thread to update this variable will be the one that appears to report back. 两个线程都在没有保护的情况下修改了变量myindex ,用于更新此变量的第二个线程将是要报告的线程。

You are also counting on your threads to begin pending on the condition before main grabs the lock and issues the broadcast, you could have a case where main gets there first and your threads won't be ready. 您还指望线程在main抢到锁并发布广播之前的条件下开始挂起,这可能会导致main首先到达那里而您的线程无法准备就绪的情况。

That should be a start. 那应该是一个开始。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM