在C中并行使用main,scanf和timer线程

时间:2014-03-12 17:50:42

标签: c multithreading timer pthreads scanf

我想实现一个围绕多线程使用的小游戏。这是概念:

  • 通过Linux控制台向用户询问问题。
  • 一旦提出此问题,就会启动15秒的计时器。
  • 如果用户想回答问题,他会在控制台中写一些内容,问题的计时器会冻结。
  • 这里开始一个5秒的新计时器,这是用户必须回答问题的有限时间。
    • 如果答案错误,则问题计时器解冻,用户可以尝试再次应答,直到问题计时器按照之前看到的相同模式达到0秒。
    • 如果答案正确,则取消问题计时器。

当然,我已经让我的程序为4个玩家处理这个游戏,但是我遇到了多线程交互的问题。

我的第一个想法包括4个线程,根据用户做什么或者定时器状态发送不同的信号条件。 (我有一个相当大的测试代码并且包含问题,我现在不想在这里显示它)

由于我是C的初学者,你能帮我解决这个多线程部分吗? 在此先感谢:)

编辑:这是第一稿而没有停止问题计时器:

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

pthread_attr_t attr_t;

void* thread_timer_q(void* arg) // Question timer thread
{
  pthread_t* a=(pthread_t*)arg;
  int t_tot=15;
  int t_ref=time(NULL);

  while(time(NULL)-t_ref<t_tot)
  {
    printf("q%d\n",time(NULL)-t_ref); // Just to see the timer going on
    sleep(1);
  }

  pthread_cancel(*a); // Here is to kill the associated scanf thread
  pthread_exit(NULL);
}

void* thread_timer_r(void* arg) // Answer timer thread
{
  pthread_t* a=(pthread_t*)arg;
  int t_tot=5;
  int t_ref=time(NULL);

  while(time(NULL)-t_ref<t_tot)
  {
    printf("...r%d\n",time(NULL)-t_ref); // To see the timer going on
    sleep(1);
  }

  pthread_cancel(*a); // Here is to kill the associated scanf thread
  pthread_exit(NULL);
}
void* thread_scanf_q(void* arg)
{
  int *x=malloc(sizeof(int));

  scanf("%x",x);

  pthread_exit((void*)x);
}

void* thread_scanf_r(void* arg) // These two scanf threads are the same for the moment
{
  int *x=malloc(sizeof(int));

  scanf("%x",x);

  pthread_exit((void*)x);
}


int main()
{
  pthread_t* timer_q=malloc(sizeof(pthread_t));
  pthread_t* timer_r=malloc(sizeof(pthread_t));
  pthread_t* scanf_q=malloc(sizeof(pthread_t));
  pthread_t* scanf_r=malloc(sizeof(pthread_t));

  void* *retval_q=malloc(sizeof(void*));
  void* *retval_r=malloc(sizeof(void*));
  int *conv=malloc(sizeof(int));
  *conv=0;

  pthread_attr_init(&attr_t);
  pthread_attr_setdetachstate(&attr_t,PTHREAD_CREATE_DETACHED); // for timers

  printf("Question asked !\n");

  pthread_create(timer_q,&attr_t,thread_timer_q,(void*)scanf_q);  

  while(*conv!=1) // While the answer is incorrect
  {
    pthread_create(scanf_q,NULL,thread_scanf_q,NULL); // Ask if the user wants to answer

    pthread_join(*scanf_q,retval_q);

    if(*retval_q==PTHREAD_CANCELED) // If scanf_q is canceled, the question timer is off
      break;
    else
    {
      pthread_create(scanf_r,NULL,thread_scanf_r,NULL); // Asking the answer to the user
      pthread_create(timer_r,&attr_t,thread_timer_r,(void*)scanf_r);  

      pthread_join(*scanf_r,retval_r);

      if(retval_r!=PTHREAD_CANCELED) // If the user has written something
      {
        conv=(int*)(*retval_r);

        if(*conv==1) // If the answer is correct
        {
          printf("Correct answer !\n");
          pthread_cancel(*timer_q);
          pthread_cancel(*timer_r);
          return 0;
        }
      } //end if(*retval_r!=PTHREAD_CANCELED)
    }// end if(*retval_q==PTHREAD_CANCELED)
  }// end while(*conv!=1)

  return 0;
}

我的问题是,如果用户回答错误的答案,问题计时器会在几秒后停止,而它应该持续长达15秒。

编辑2:问题已解决=&gt;如果答案是错误的,我没有关闭答案计时器线程,所以我只想在内部添加:

if(*conv!=1)
{
  pthread_cancel(*timer_r);
}

以下是当用户想要回答问题时冻结问题计时器的新完整代码:

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

pthread_mutex_t mut=PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t freeze=PTHREAD_COND_INITIALIZER;
pthread_cond_t unfreeze=PTHREAD_COND_INITIALIZER;

pthread_attr_t attr_t;

void* thread_timer_q(void* arg)
{
  pthread_t* a=(pthread_t*)arg;
  struct timespec ts={time(NULL)+1,0};
  int t_tot=15;
  int t_ref=time(NULL);

  while(time(NULL)-t_ref<t_tot)
  {
    if(ETIMEDOUT==pthread_cond_timedwait(&freeze,&mut,&ts))
    {
      ts.tv_sec++;
      printf("q%d\n",time(NULL)-t_ref);
    }
    else
    {
      printf("freezed\n");//
      t_tot-=time(NULL)-t_ref;

      while(1)
      {
        if(ETIMEDOUT==pthread_cond_timedwait(&unfreeze,&mut,&ts))
        {
          ts.tv_sec++;
        }
        else
        {
          printf("Unfreezed\n");
          t_ref=time(NULL);
          break;
        }
      }//end while(1)
    }//end if(ETIMEDOUT ...)
  }//end while

  pthread_cancel(*a);
  pthread_exit(NULL);
}

void* thread_timer_r(void* arg)
{
  pthread_t* a=(pthread_t*)arg;
  int t_tot=5;
  int t_ref=time(NULL);

  while(time(NULL)-t_ref<t_tot)
  {
    printf("...r%d\n",time(NULL)-t_ref);
    sleep(1);
  }

  pthread_cancel(*a);
  pthread_exit(NULL);
}

void* thread_scanf(void* arg)
{
  int *x=malloc(sizeof(int));

  scanf("%x",x);

  pthread_exit((void*)x);
}


int main()
{
  pthread_t* timer_q=malloc(sizeof(pthread_t));
  pthread_t* timer_r=malloc(sizeof(pthread_t));
  pthread_t* scanf_q=malloc(sizeof(pthread_t));
  pthread_t* scanf_r=malloc(sizeof(pthread_t));

  void* *retval_q=malloc(sizeof(void*));
  void* *retval_r=malloc(sizeof(void*));
  int *conv=malloc(sizeof(int));

  pthread_attr_init(&attr_t);
  pthread_attr_setdetachstate(&attr_t,PTHREAD_CREATE_DETACHED); // for timers

  while(1)
  {
    *conv=0;

    printf("Question asked !\n");

    pthread_create(timer_q,&attr_t,thread_timer_q,(void*)scanf_q);  

    while(*conv!=1)
    {
      pthread_create(scanf_q,NULL,thread_scanf,NULL);

      pthread_join(*scanf_q,retval_q);

      if(*retval_q==PTHREAD_CANCELED)
        break;
      else
      {
        pthread_mutex_lock(&mut);
        pthread_cond_signal(&freeze);
        pthread_mutex_unlock(&mut);

        pthread_create(scanf_r,NULL,thread_scanf,NULL);
        pthread_create(timer_r,&attr_t,thread_timer_r,(void*)scanf_r);  

        pthread_join(*scanf_r,retval_r);

        if(*retval_r==PTHREAD_CANCELED)
        {
          pthread_mutex_lock(&mut);
          pthread_cond_signal(&unfreeze);
          pthread_mutex_unlock(&mut);
        }
        else
        {
          conv=(int*)(*retval_r);

          if(*conv==1)
          {
            printf("Correct answer !\n");
            pthread_cancel(*timer_q);
            pthread_cancel(*timer_r);
            break;
          }
          else
          {
            pthread_mutex_lock(&mut);
            pthread_cond_signal(&unfreeze);
            pthread_mutex_unlock(&mut);

            pthread_cancel(*timer_r);
          }// end if(*conv==1)
        }// end if(*retval_r=...)
      }// end if(*retval_q=...)
    }// end while(*conv!=1)
  }// end while(1)
  return 0;
}

0 个答案:

没有答案