我正在尝试制作多线程c ++程序。 我一直在测试我的程序,有时会得到SIGSEGV(分段错误)。 我发现指针变量只复制了部分内存,而不是全部。
以下是我的部分代码。
课程定义
class Message
{
public:
Message() {}
virtual ~Message() {}
virtual void execute() = 0; //do something...
}
class Job
{
public:
Job();
~Job();
void post(Message *message);
void execute(Message *message);
private:
Message *_queue[1024] = {nullptr,};
volatile int _head = 0;
int _tail = 0;
};
4个线程正在运行并调用相同Job类实例的方法。
线程1调用此方法。
void Job::execute(Message *message)
{
if (message != nullptr)
{
int index = __sync_fetch_and_add(&_head, 1) % 1024;
_queue[index] = message;
}
while (_tail != _head)
{
int index = _tail % 1024;
Message *workingMessage = _queue[index];
while (workingMessage == nullptr)
{
sched_yield();
workingMessage = _queue[index];
}
workingMessage->execute();
_queue[index] = nullptr;
++_tail; //this is changed on Thread 1 only!
}
}
线程2~4调用此方法。
void Job::post(Message *message)
{
int index = __sync_fetch_and_add(&_head, 1) % 1024;
_queue[index] = message;
}
几分钟后,我在Thread 1的这一部分遇到了SIGSEGV崩溃。
workingMessage->execute(); // Crash!
在调试器上,workingMessage只有_queue [Index]值的一部分。 例如,
_queue[index] : 0x7fffdc09abdb
workingMessage : 0xffdc09abdb
或
_queue[index] : 0x7fffe8048e35
workingMessage : 0x7fffe8040000
像这些情况一样。
我试过用std :: atomic<消息*>对于_queue和workingMessage,发生了同样的崩溃。
怎么了?我在CentOS 7上编译并测试了这个,gcc 4.8.5。