在线程调用 pthread_wait 现在发出信号后,执行发生在哪里?
Where does the execution happen after a thread has called pthread_wait is now signalled?
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cv = PTHREAD_COND_INITIALIZER;
void thread_1() {
pthread_mutex_lock(&mutex);
some_cond = true;
pthread_cond_signal(&cv);
pthread_mutex_unlock(&mutex);
}
void thread_2() {
pthread_mutex_lock(&mutex);
while (!some_cond)
pthread_cond_wait(&cv, &mutex);
printf("test"); // After signaling from thread_1, does this get ran after?
pthread_mutex_unlock(&mutex);
}
假设 thread_2 调用 pthread_cond_wait.
Thread_1 出现然后 pthread_cond_signal.
我了解到 thread_2 会在调用 pthread_cond_wait 时被阻塞,并解锁其互斥量。
但是,我很困惑 thread_1 调用 signal 之后 thread_2 中的哪一行代码会 运行 .
在thread_2中,当它被唤醒时,它是否从thread_2现在可以访问互斥锁的地方开始,然后锁定它,然后再次检查 while 条件,发现它现在为真并打印 test?
或者 thread_2 是否可以访问其互斥量,然后将其锁定,然后 print("test") 是 运行 之后(忽略while 条件)?
However, I am confuse on which line of code will run in thread_2 after thread_1 calls signal.
实际上,在thread_1调用pthread_cond_signal
之后,什么也不会发生,因为thread_1仍然有互斥锁。 thread_1 上的下一条指令是 pthread_mutex_unlock
。然后 thread_2 将停止阻塞 pthread_cond_wait
并自动 acquire
锁定。 while 条件然后将检查条件,中断并打印“测试”。
关于:
void thread_1() {
和
void thread_2() {
这些不是线程函数的有效签名!也许你的意思是:
void * thread_1( void *arg )
和
void * thread_2( void *arg )
另外,运行关闭线程结束函数无效。建议每个线程中的最后一个语句是:
pthread_exit( void );
无法保证哪个线程先运行。如果 thread_2()
先运行,那么互斥量将被锁定并且 thread_2() 将永远等待 pthread_condition(),但由于 thread_1()
将立即被阻止试图获得互斥锁。 NOTHING(更多)将在这些线程中执行。
通常,函数:pthread_wait()
在可执行文件的同一部分调用函数:pthread_create()
。这会暂停调用代码,直到某个线程退出(在上面的场景中,没有线程会退出
调用pthread_cond_signal
时,另一个线程中没有特定的代码行运行。如果您希望特定行以特定顺序 运行,则必须将所有这些行放入一个线程的路径中。
当调用 pthread_cond_signal
时,另一个线程几乎可以做任何事情。我们知道的一件事是,
因为信号调用在互斥体内部,所以另一个线程不在互斥体中。我们可以标记其他可以的地方:
void thread_2() {
// (A) Either here, or earlier.
pthread_mutex_lock(&mutex);
while (!some_cond)
pthread_cond_wait(&cv, &mutex); // (B) Or here.
printf("test"); // After signaling from thread_1, does this get ran after?
pthread_mutex_unlock(&mutex);
// (C) Or else here, or farther
}
只有当 some_cond
已经为真时,另一个线程才能位于 C
。如果 some_cond
假设为假,我们可以忘记 C
.
如果 A
是这种情况,则线程要么正在执行 pthread_mutex_lock
之前的代码(我们可以称其为 A1
),要么它已经锁定并且现在等待互斥锁 (A2
).
调用 pthread_cond_signal
的线程拥有互斥锁,并在调用后继续这样做。所以有可能另一个线程在 A1
,然后继续 A2
(等待互斥体)。
如果线程处于B
:等待条件变量,信号可能会唤醒它。在从 pthread_cond_wait
returning 之前,它必须 re-acquire 互斥锁,所以它可能会卡在那里等待。在任何情况下,在 B
状态下,在第一个线程执行 pthread_mutex_unlock
.
之前,另一个线程无法从 pthread_cond_wait
调用中 return
有可能另一个线程处于A1
状态(还没有达到互斥量),而信号器完成了一切:设置变量,发出信号,释放互斥量。然后另一个线程会不等待就去抢这个互斥锁,看到条件为真,就离开这个互斥锁。信号是无关紧要的,因为 pthread_cond_wait
永远不会被调用。
如果您正在使用共享变量和显式同步原语(如互斥锁和条件)进行编程,则必须推理所有可能发生的情况:其他线程可能处于的所有相关状态。
其他几个例子都很好,但它们似乎都掩盖了我认为是 OP 的关键混淆点。
I am confuse on which line of code will run in thread_2 after thread_1 calls signal.
这里没有魔法。 pthread_cond_wait()
是一个函数,它的行为就像一个函数。当它的等待结束,并且它重新获得了互斥量时,它 returns 给它的调用者。控制从那里正常进行,就像在任何其他函数调用之后一样 returns.
在这种特殊情况下,函数调用是 while
循环主体中的唯一语句,因此调用 returns 之后发生的下一件事将是 while
正在重新评估条件。
请注意,pthread_cond_wait
的调用者可以而且应该检查 return 值以捕获和处理它指示发生错误的情况,就像对指示错误的其他函数所做的一样通过它们的 return 值的错误条件。
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cv = PTHREAD_COND_INITIALIZER;
void thread_1() {
pthread_mutex_lock(&mutex);
some_cond = true;
pthread_cond_signal(&cv);
pthread_mutex_unlock(&mutex);
}
void thread_2() {
pthread_mutex_lock(&mutex);
while (!some_cond)
pthread_cond_wait(&cv, &mutex);
printf("test"); // After signaling from thread_1, does this get ran after?
pthread_mutex_unlock(&mutex);
}
假设 thread_2 调用 pthread_cond_wait.
Thread_1 出现然后 pthread_cond_signal.
我了解到 thread_2 会在调用 pthread_cond_wait 时被阻塞,并解锁其互斥量。 但是,我很困惑 thread_1 调用 signal 之后 thread_2 中的哪一行代码会 运行 .
在thread_2中,当它被唤醒时,它是否从thread_2现在可以访问互斥锁的地方开始,然后锁定它,然后再次检查 while 条件,发现它现在为真并打印 test?
或者 thread_2 是否可以访问其互斥量,然后将其锁定,然后 print("test") 是 运行 之后(忽略while 条件)?
However, I am confuse on which line of code will run in thread_2 after thread_1 calls signal.
实际上,在thread_1调用pthread_cond_signal
之后,什么也不会发生,因为thread_1仍然有互斥锁。 thread_1 上的下一条指令是 pthread_mutex_unlock
。然后 thread_2 将停止阻塞 pthread_cond_wait
并自动 acquire
锁定。 while 条件然后将检查条件,中断并打印“测试”。
关于:
void thread_1() {
和
void thread_2() {
这些不是线程函数的有效签名!也许你的意思是:
void * thread_1( void *arg )
和
void * thread_2( void *arg )
另外,运行关闭线程结束函数无效。建议每个线程中的最后一个语句是:
pthread_exit( void );
无法保证哪个线程先运行。如果 thread_2()
先运行,那么互斥量将被锁定并且 thread_2() 将永远等待 pthread_condition(),但由于 thread_1()
将立即被阻止试图获得互斥锁。 NOTHING(更多)将在这些线程中执行。
通常,函数:pthread_wait()
在可执行文件的同一部分调用函数:pthread_create()
。这会暂停调用代码,直到某个线程退出(在上面的场景中,没有线程会退出
调用pthread_cond_signal
时,另一个线程中没有特定的代码行运行。如果您希望特定行以特定顺序 运行,则必须将所有这些行放入一个线程的路径中。
当调用 pthread_cond_signal
时,另一个线程几乎可以做任何事情。我们知道的一件事是,
因为信号调用在互斥体内部,所以另一个线程不在互斥体中。我们可以标记其他可以的地方:
void thread_2() {
// (A) Either here, or earlier.
pthread_mutex_lock(&mutex);
while (!some_cond)
pthread_cond_wait(&cv, &mutex); // (B) Or here.
printf("test"); // After signaling from thread_1, does this get ran after?
pthread_mutex_unlock(&mutex);
// (C) Or else here, or farther
}
只有当 some_cond
已经为真时,另一个线程才能位于 C
。如果 some_cond
假设为假,我们可以忘记 C
.
如果 A
是这种情况,则线程要么正在执行 pthread_mutex_lock
之前的代码(我们可以称其为 A1
),要么它已经锁定并且现在等待互斥锁 (A2
).
调用 pthread_cond_signal
的线程拥有互斥锁,并在调用后继续这样做。所以有可能另一个线程在 A1
,然后继续 A2
(等待互斥体)。
如果线程处于B
:等待条件变量,信号可能会唤醒它。在从 pthread_cond_wait
returning 之前,它必须 re-acquire 互斥锁,所以它可能会卡在那里等待。在任何情况下,在 B
状态下,在第一个线程执行 pthread_mutex_unlock
.
pthread_cond_wait
调用中 return
有可能另一个线程处于A1
状态(还没有达到互斥量),而信号器完成了一切:设置变量,发出信号,释放互斥量。然后另一个线程会不等待就去抢这个互斥锁,看到条件为真,就离开这个互斥锁。信号是无关紧要的,因为 pthread_cond_wait
永远不会被调用。
如果您正在使用共享变量和显式同步原语(如互斥锁和条件)进行编程,则必须推理所有可能发生的情况:其他线程可能处于的所有相关状态。
其他几个例子都很好,但它们似乎都掩盖了我认为是 OP 的关键混淆点。
I am confuse on which line of code will run in thread_2 after thread_1 calls signal.
这里没有魔法。 pthread_cond_wait()
是一个函数,它的行为就像一个函数。当它的等待结束,并且它重新获得了互斥量时,它 returns 给它的调用者。控制从那里正常进行,就像在任何其他函数调用之后一样 returns.
在这种特殊情况下,函数调用是 while
循环主体中的唯一语句,因此调用 returns 之后发生的下一件事将是 while
正在重新评估条件。
请注意,pthread_cond_wait
的调用者可以而且应该检查 return 值以捕获和处理它指示发生错误的情况,就像对指示错误的其他函数所做的一样通过它们的 return 值的错误条件。