Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C语言中主线程、scanf线程和定时器线程的并行使用_C_Multithreading_Timer_Pthreads_Scanf - Fatal编程技术网

C语言中主线程、scanf线程和定时器线程的并行使用

C语言中主线程、scanf线程和定时器线程的并行使用,c,multithreading,timer,pthreads,scanf,C,Multithreading,Timer,Pthreads,Scanf,我想实现一个关于使用多线程的小游戏。这是一个概念: 通过Linux控制台向用户提问 一旦提出这个问题,15秒的计时器就会启动 如果用户想回答问题,他会在控制台中写一些东西,问题的计时器就会冻结 在这里,一个5秒的新计时器启动,这是用户回答问题的有限时间。 如果答案是错误的,那么问题计时器将解冻,用户可以按照前面看到的相同模式再次尝试回答,直到问题计时器达到0秒 如果答案正确,则问题计时器被取消 当然,我已经为4名玩家编写了这个游戏的程序,但是我在多线程交互方面遇到了问题 我的第一个想法由

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

  • 通过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;
}
以下是新的完整代码,当用户想要回答问题时,问题计时器将冻结:

#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;
}
#包括
#包括
#包括
#包括
pthread\u mutex\u t mut=pthread\u mutex\u初始值设定项;
pthread_cond_t freeze=pthread_cond_初始值设定项;
pthread_cond_t unfreeze=pthread_cond_初始值设定项;
pthread_attr_t attr_t;
空*线程\计时器\ q(空*参数)
{
pthread_t*a=(pthread_t*)参数;
struct timespec ts={time(NULL)+1,0};
int t_tot=15;
int t_ref=时间(空);

while(time(NULL)-t_ref这似乎是一个相当宽泛的问题。我建议将程序剥离为相当简单的部分,以隔离您混淆的部分,然后发布代码。这样做,您可能会自己发现问题,如果不是,您将更容易调试。找到答案,关闭主题。
#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;
}