【发布时间】:2014-05-26 00:44:01
【问题描述】:
我在调试我编写的以下程序时遇到问题。这个想法是有两个单独的线程;一个线程执行 5 秒倒计时,而另一个线程等待用户的键输入。无论哪个线程先完成,都应该取消同级线程并退出程序。但是,下面的代码只是挂起。
任何帮助将不胜感激,但我将非常感谢您对问题的解释。
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h> // For sleep()
#define NUM_THREADS 2
// The stuct to be passed as an argument to the countdown routine
typedef struct countdown_struct {
pthread_t *thread;
signed int num_secs;
} CountdownStruct;
// Struct for passing to the input wait routine
typedef struct wait_struct {
pthread_t *thread;
int *key;
} WaitStruct;
// Countdown routine; simply acts as a timer counting down
void * countdown(void *args)
{
CountdownStruct *cd_str = (CountdownStruct *)args;
signed int secs = cd_str->num_secs;
printf("Will use default setting in %d seconds...", secs);
while (secs >= 0)
{
sleep(1);
secs -= 1;
printf("Will use default setting in %d seconds...", secs);
}
// Cancel the other struct
pthread_cancel(*(cd_str->thread));
return NULL;
}
// Waits for the user to pass input through the tty
void * wait_for_input(void *args)
{
WaitStruct *wait_str = (WaitStruct *) args;
int c = 0;
do {
c = getchar();
} while (!(c == '1' || c == '2'));
*(wait_str->key) = c;
// Cancel the other thread
pthread_cancel(*(wait_str->thread));
return NULL;
}
int main(int argc, char **argv)
{
pthread_t wait_thread;
pthread_t countdown_thread;
pthread_attr_t attr;
int key=0;
long numMillis=5000;
int rc=0;
int status=0;
// Create the structs to be passe as paramaters to both routines
CountdownStruct *cd_str = (CountdownStruct *) malloc(sizeof(CountdownStruct));
if (cd_str == NULL)
{
printf("Couldn't create the countdown struct. Aborting...");
return -1;
}
cd_str->thread = &wait_thread;
cd_str->num_secs = 5;
WaitStruct *wait_str = (WaitStruct *) malloc(sizeof(WaitStruct));
if (wait_str == NULL)
{
printf("Couldn't create the iput wait struct. Aborting...");
return -1;
}
wait_str->thread = &countdown_thread;
wait_str->key = &key;
// Create the joinable attribute
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
// Create both threads
rc = pthread_create(&countdown_thread, &attr, countdown, (void *) cd_str);
if (rc) { printf("Error with the thread creation!"); exit(-1); }
rc = pthread_create(&wait_thread, &attr, wait_for_input, (void *) wait_str);
if (rc) { printf("Error with the thread creation!"); exit(-1); }
// Destroy the pthread_attribute
pthread_attr_destroy(&attr);
// now join on the threads and wait for main
pthread_join(wait_thread, NULL);
pthread_join(countdown_thread, NULL);
// Call pthread_exit
pthread_exit(NULL);
// Free the function structs
free(cd_str);
free(wait_str);
}
【问题讨论】:
-
我注意到在几个地方,包括stackoverflow.com/questions/433989/posix-cancellation-points getchar() 不需要是取消点。我想在标准输入上做一个选择会给你超时和读取。
-
@dennis 即使调用 getchar() 超时线程也永远不会完成并关闭程序。这是最令人费解的一点。感谢您的帮助,但 select() 是一种解决方法,不能解决此处所述的问题
-
你的意思是没有 getchar() 调用?然后 wait_for_input 线程将处于自旋循环中并且永远不会达到取消点。连接会挂起,阻止 main 退出。还是您只是让 wait_for_input 循环失败?
-
剪切并粘贴到我的 Fedora 19 机器上,编译,超时后退出。 (数到 -1,但足够接近。)
-
@dennis 我失败了。这很奇怪;超时循环不会为我退出。我在 Mac 上运行,这可能是平台问题吗?我现在试试你的答案,看看它是否适合我
标签: c multithreading pthreads