我正在尝试实现粗线程中断。
经常检查'interruptRequested'变量。在操作系统课程中,我们了解了饥饿 - 这可能在这里或在类似的情况下吗?我知道示例程序的行为与我在运行它时的预期相同,但它可能只是一个侥幸。
以下是我正在做的简化版本:
//Compile with -lpthread
#include <iostream>
#include <signal.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>
#include <pthread.h>
using namespace std;
bool interruptRequested;
pthread_mutex_t spamMutex;
void *Spam(void *);
int main(int argc, char *argv[])
{
pthread_t tid;
interruptRequested = false;
unsigned long long int timeStarted = time(NULL);
pthread_create(&tid, NULL, Spam, NULL);
unsigned long long int difference = 0;
while (true)
{
pthread_yield();
difference = (time(NULL) - timeStarted);
if ( difference >= 5)//Spam the terminal for 5 seconds
{
//while (pthread_mutex_trylock(&spamMutex));
interruptRequested = true;
//pthread_mutex_unlock(&spamMutex);
break;
}
}
return 0;
}
void *Spam (void *arg)
{
while (true)
{
//while (pthread_mutex_trylock(&spamMutex));
if (interruptRequested == true)
{
//pthread_mutex_unlock(&spamMutex);
break;
}
//pthread_mutex_unlock(&spamMutex);
cout << "I'm an ugly elf" << endl;
pthread_yield();
}
interruptRequested = false;
pthread_exit (0);
}
实际上,在实际代码中我没有使用时差方法。我的程序将收到来自服务器的消息,此时我需要中断该线程。
答案 0 :(得分:1)
如上所述,此代码不一定能保证有效,因为编译器可能会优化对工作线程内部interruptRequested
的检查,因为它永远不会写入函数内部。这意味着生成的代码可能只有一个while (true)
循环(或类似的东西)。
为了防止这种情况发生,您需要确保编译器识别出该变量可能在其他地方被修改。您可以通过标记interruptRequested
volatile
来执行此操作,这表明编译器不应该对其进行优化。使用互斥锁也是一个好主意,因为大多数编译器都足够聪明,可以识别使用互斥锁表示互斥锁内部引用的变量可以在外部修改。
答案 1 :(得分:0)
我认为通常共享数据应该使用互斥锁处理。
在这种特定情况下,只有一个线程更新控制变量,因此使用互斥锁可能过多。您可以在几毫秒的活动循环中进行时间休眠,以使主循环不时处于活动状态。
答案 2 :(得分:0)
是的,您必须首先使用互斥锁来保护对相应块中的interruptRequested
的读写操作。
即使出现按预期工作,也可能实际上没有。软件无法接受99%的成功率。同样,你的测试程序是微不足道的 - 在现实世界中它会(无声地或神秘地)失败的可能性很大。
使用volatile(或在许多情况下是原子)作为锁的替代是坏的想法。这个模型最终会失败,虽然它常常出现在轻负载下正常工作。有一些极端情况,但你应该放弃volatile的关联,以取代使用锁定的正确设计。实际上,您可以通过将interruptRequested
设为int
并仅使用递增/递减来测试此操作。在重载下 - 你可以快速超过[0 ... 1]。
在声明/读/写interruptRequested时,你会经常使用volatile和/或atomics(同样,我建议使用int / inc / dec / bounds检查,特别是在你学习的时候)。如果读取和写入都被锁定(在这种情况下应该是这样),使用原子读/写将无济于事。
关于您的计划,条件(pthread_cond_t
)可能是一个不错的选择。