我想实现一个围绕多线程使用的小游戏。这是概念:
当然,我已经让我的程序为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;
}