C 处理两个线程,一个正在休眠,另一个正在等待输入
问题:创建一个接受用户输入但在几秒钟后超时的程序(假设现在是2秒钟) 方法:我创建了两个线程,一个线程等待用户输入(C 处理两个线程,一个正在休眠,另一个正在等待输入,c,multithreading,pthreads,C,Multithreading,Pthreads,问题:创建一个接受用户输入但在几秒钟后超时的程序(假设现在是2秒钟) 方法:我创建了两个线程,一个线程等待用户输入(inputThread使用tid[0]),另一个线程睡眠2秒钟(sleepThread使用tid[1])。我从另一个线程的例程中取消一个线程,如下所示: #include <stdio.h> #include <unistd.h> #include <pthread.h> pthread_t tid[2]; void* inputThread
inputThread
使用tid[0]
),另一个线程睡眠2秒钟(sleepThread
使用tid[1]
)。我从另一个线程的例程中取消一个线程,如下所示:
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
pthread_t tid[2];
void* inputThread()
{
int n;
printf("Enter number:");
// wait for input; if input is given then go ahead and cancel the sleeper thread.
scanf("%d",&n);
// cancel the sleeper thread
pthread_cancel(tid[1]);
printf("Got value:%d\n",n);
}
void* sleepThread()
{
// sleep for 2 seconds and cancel the input thread.
sleep(2);
// cancel the input thread
pthread_cancel(tid[0]);
printf("\nNo value entered!\n");
}
int main(int argc, char const *argv[])
{
int r1,r2,r3,r4;
// input taking thread
r1 = pthread_create(&tid[0],NULL,inputThread,NULL);
// sleeping thread
r2 = pthread_create(&tid[1],NULL,sleepThread,NULL);
r3 = pthread_join(tid[0],NULL);
r4 = pthread_join(tid[1],NULL);
return 0;
}
#包括
#包括
#包括
pthread_t tid[2];
void*inputThread()
{
int n;
printf(“输入编号:”);
//等待输入;如果输入已给出,则继续并取消休眠线程。
scanf(“%d”和“&n”);
//取消枕木线
pthread_cancel(tid[1]);
printf(“获取值:%d\n”,n);
}
void*sleepThread()
{
//睡眠2秒钟并取消输入线程。
睡眠(2);
//取消输入线程
pthread_cancel(tid[0]);
printf(“\n未输入值!\n”);
}
int main(int argc,char const*argv[]
{
int r1、r2、r3、r4;
//输入获取线程
r1=pthread_create(&tid[0],NULL,inputThread,NULL);
//睡线
r2=pthread_create(&tid[1],NULL,sleepThread,NULL);
r3=pthread_join(tid[0],NULL);
r4=pthread_join(tid[1],NULL);
返回0;
}
到目前为止,该计划按预期运行
但是我的朋友说它不能保证工作,因为它取决于线程的调度方式。他试着向我解释,但我听不懂。他还说,pthread\u cancel
只是一个取消线程的请求,它可能不会成功
因此,请有人指出潜在的错误和最佳做法,以避免同样的情况。为保证程序正常运行所做的任何更改也将受到赞赏。您的朋友关于
pthread\u cancel
是取消线程的请求,可能不会总是成功
关于日程安排的部分,你需要提供他有哪些论点
为了解决您的问题,您可以放弃同时使用线程(除非这是您的任务的要求),而使用
这将使解决方案不可移植(仅符合POSIX),但pthreads
无论如何也不可移植
select
允许您等待文件描述符(在本例中为0
)以获取可用于读取的数据。它还允许您设置超时
fd_set set;
FD_ZERO(&set);
FD_SET(0, &set);
struct timeval timeout;
timeout.tv_sec = 2;
timeout.tv_usec = 0;
int ret = select(1, &set, NULL, NULL, &timeout);
if (ret == 1) {
char buffer[20];
int n;
read(0, buffer, 20);
sscanf(buffer, "%d", &n);
printf("Got value:%d\n",n);
} else {
printf("Time out\n");
}
该函数调用线程上的线程取消处理程序,这些处理程序返回后将调用线程的析构函数,析构函数反过来将终止线程
因为它是一个请求,所以可能会失败,这由pthread\u cancel
返回一个非零整数表示
如果您使用两个以上的线程来执行此操作,或者在同一进程中有多个线程正在访问stdin,您可能会让线程等待访问stdin,从而导致所需的行为延迟。您的朋友是对的,我认为他的意思是,您不能假定知道哪个线程首先运行/完成。 但两个线程都将被调度,因此thread1有时间请求用户输入并等待一点输入 我看不出有什么大问题,如果可以的话,就不要太担心
但是,您可以使用SIGALRM信号来代替
sleep
,但它涉及掩码,需要花费更多的时间来理解(我正在做的是:检查task2
函数及其使用的掩码,如果您需要示例)。只有一个线程正在访问stdin
。您可以建议使用pthread\u cancel
的任何替代方法吗?@RahulBharadwaj是的,您可以使用,它作为void的返回类型,永不失败。@JoshWeinsteinpthread\u exit
,终止调用线程。因此,必须从等待的线程调用它,这是不可能的。没有可靠的方法可以从另一个线程杀死一个线程。感谢您提供的解决方案。使用线程不是必需的,但我们使用线程只是为了学习线程库。如果只使用线程,我如何处理它?只有一个线程可以吗?@RahulBharadwaj我给出的解决方案是使用一个线程。如果你想使用多个线程,正确的方法是有一个睡眠线程(就像你现在拥有的那样)。超时后,它将volatile
标志设置为0。主线程将stdin
(0)fd设置为非阻塞模式,并继续尝试读取(适当的睡眠时间为10毫秒)。每次重复之前,它都会检查volatile变量。这样你可以得到同样的行为。好的,我理解。我将尝试使用main
thread之外的一个额外线程来实现。@RahulBharadwaj您可以了解如何将0fd设置为非阻塞模式。虽然我会建议,fd先看,然后再看。如果将0 fd设置为非阻塞,我不确定标准库代码(如scanf、gets)的行为。如果用户不按enter键,则显示的代码不会超时。我使用了sigprocmask
和信号
。从来没有想过,我会尝试使用它来实现它,谢谢!