问题描述
我有两个线程
xThread
:连续打印的X控制台上
inputThread
:获取从标准输入输入
在连续打印时,用户输入C或C
停止 #包括LT&;&stdio.h中GT;
#包括LT&; SYS / select.h>
#包括LT&;&pthreads.h中GT;
#定义睡眠(0)INT read_c = 0;
pthread_mutex_t read_c_mutex = PTHREAD_MUTEX_INITIALIZER;无效* inputThread_fn(无效* ARG)
{
焦炭inputChar;而(1)
{
S; 的printf(\\ nChecking输入);
scanf函数(%C,&安培; inputChar);
如果(inputChar =='C'|| inputChar =='C')
{
pthread_mutex_trylock(安培; read_c_mutex); / *< - 这必须_lock?
因为使用的tryLock的,即使我不AQUIRE锁我继续和修改
变量?* /
read_c = 1;
调用pthread_mutex_unlock(安培; read_c_mutex);
了pthread_exit(NULL);
}
}}无效* xThread_fn(无效* ARG)
{
而(1)
{
S;
pthread_mutex_trylock(安培; read_c_mutex);
如果(!read_c)
的printf(X);
其他
了pthread_exit(NULL);
调用pthread_mutex_unlock(安培; read_c_mutex);
}}无效* yThread_fn(无效* ARG)
{
而(1)
{
S;
pthread_mutex_trylock(安培; read_c_mutex);
如果(!read_c)
的printf(Y);
其他
了pthread_exit(NULL);
调用pthread_mutex_unlock(安培; read_c_mutex);
}}
诠释的main()
{
的pthread_t xThread,yThread,inputThread;在pthread_create(安培; xThread,NULL xThread_fn,NULL);
在pthread_create(安培; inputThread,NULL inputThread_fn,NULL);在pthread_join(xThread,NULL);
在pthread_join(inputThread,NULL);返回0;
}
当我使用睡眠(1)
的线程都催生和[不论哪个线程首先启动]当程序到达 scanf函数
在 inputThread
它停止对用户输入和code不会继续,直到我输入的输入。
当我执行code。与睡眠(0)
, scanf函数
不停止对输入,它使打印'X',直到我进入'C'或'C'
是否睡眠()
与 scanf函数
以某种方式干预?
注意:我知道的选择
被用于非阻塞输入。我曾尝试过相同和code运行正常。我只想在上述情况下知道为什么不一致的行为出现?
更新(使用的tryLock
)
无效* inputThread_fn(无效* ARG)
{
焦炭inputChar; 而(1)
{
S;
scanf函数(%C,&安培; inputChar);
如果(inputChar =='C'|| inputChar =='C')
{
pthread_mutex_trylock(安培; read_c_mutex);
read_c = 1;
调用pthread_mutex_unlock(安培; read_c_mutex);
了pthread_exit(NULL);
}
}
}无效* xThread_fn(无效* ARG)
{
而(1)
{
S;
pthread_mutex_trylock(安培; read_c_mutex);
如果(!read_c)
{
调用pthread_mutex_unlock(安培; read_c_mutex);
的printf(X);
}
其他
{
调用pthread_mutex_unlock(安培; read_c_mutex);
了pthread_exit(NULL);
}
fflush(标准输出);
}
}无效* yThread_fn(无效* ARG)
{
而(1)
{
S;
pthread_mutex_trylock(安培; read_c_mutex);
如果(!read_c)
{
调用pthread_mutex_unlock(安培; read_c_mutex);
的printf(Z);
fflush(标准输出);
}
其他
{
调用pthread_mutex_unlock(安培; read_c_mutex);
了pthread_exit(NULL);
}
}
}
您没有看到输出的原因是因为你没有刷新缓冲区。
您不需要刷新与缓冲区的原因睡眠(0)
是因为作家线程写入如此多的数据缓冲区填满,并自动刷新
的#define SLEEP_TIME 1无效* xThread_fn(无效* ARG)
{
而(1){
睡眠(SLEEP_TIME);
调用pthread_mutex_lock(安培; read_c_mutex);
如果(read_c){
调用pthread_mutex_unlock(安培; read_c_mutex);
返回NULL;
}
调用pthread_mutex_unlock(安培; read_c_mutex);
的printf(X);
fflush(标准输出); //< - 必要
}
}
不要使用 pthread_mutex_trylock()
不要使用 pthread_mutex_trylock()
在这里。这是错误的。
之间的区别锁()
和的tryLock()
是锁()
将始终成功,但的tryLock()
有时会失败。这就是为什么它被称为试一试。
由于的tryLock()
有时会失败,你必须处理它失败的情况。您code不处理的话:它只是向前犁,pretending它获得锁。因此,假设的tryLock()
不锁定互斥。会发生什么?
pthread_mutex_trylock(安培; read_c_mutex); //可能会失败(即不锁互斥)
read_c = 1; //修改共享状态(错!)
调用pthread_mutex_unlock(安培; read_c_mutex); //解锁互斥(错!)
此外,还有的code应如何处理的tryLock()
失败的问题。如果你不能回答这个问题,那么默认的答案是用锁()
在读线程,则不能使用的tryLock()
,因为你的有无的锁定互斥:
INT R = pthread_mutex_trylock(安培; read_c_mutex);
如果(R!= 0){
//呃......是我们应该在这里做什么?再试一次?
}其他{
read_c = 1;
调用pthread_mutex_unlock(安培; read_c_mutex);
}
在写线程,有一个在不使用点的tryLock()
:
INT R = pthread_mutex_trylock(安培; read_c_mutex);
如果(R!= 0){
//好,就再试下一个循环...
}其他{
如果(read_c){
调用pthread_mutex_unlock(安培; read_c_mutex);
了pthread_exit(NULL);
}其他{
调用pthread_mutex_unlock(安培; read_c_mutex);
}
}
然而,这是完全没有意义的。唯一的原因的tryLock()
将写线程失败是,如果读线程拥有锁,只发生,如果它目前在制定的过程中 read_c = 1;
。所以,你不妨等到它完成,因为你知道你无论如何要退出(为什么你知道后,用户已经暗示你的程序停止写更多的产出?)
只要使用锁()
。你会使用锁()
的99%的时间,而的tryLock()
为其他1%。
:在锁()
功能可以失败,但是这通常意味着你已经被滥用互斥
关于误解锁()
和的tryLock()
您说,这大约的tryLock()
:
I think there is a very fundamental misunderstanding here about the nature of mutexes. If another thread weren't accessing the variable at the same time, then you wouldn't need a mutex at all.
Suppose you're doing important work at the office, and you need to use the photocopier. Only one person can use the photocopier at a time. You go to the photocopier and someone's already using it.
If you wait in line until it's your turn, then that's
lock()
.If you give up and go back to your desk, then that's
trylock()
. (Your program actually ignores the return code fortrylock()
, so you basically start mashing buttons on the photocopier even if someone else is using it.)
Now imagine that it takes one minute to use the photocopier, only two people ever use the photocopier, and they only use the photocopier once every twenty years.
If you use
lock()
, then you wait in line for at most one minute before using the photocopier.If you use
trylock()
, then you give up and go back to your desk and wait twenty years before trying the photocopier again.
It doesn't make any sense to use trylock()
, does it? Are your threads so impatient that they can't spend even one minute in line once every twenty years?
Now your boss comes down and said, "Where is that report I asked you to photocopy?" And you say, "Well, I went to the photocopier six years ago but someone was using it."
The numbers (one minute every twenty years) are based on Latency Numbers Every Programmer Should Know, where it notes that locking/unlocking a mutex is about 25ns. So if we pretend that it takes one minute to lock and then unlock a mutex, then sleep(1)
causes the thread to wait for twenty years.
这篇关于是否睡眠()与干扰scanf函数()?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!