У меня есть программа, которая обрабатывает данные нейронного пика , которые транслируются в пакетах UDP в локальной сети.
Моя текущая программа имеет два потока: поток пользовательского интерфейса и рабочий поток.Рабочий поток просто прослушивает пакеты данных, анализирует их и делает их доступными для потока пользовательского интерфейса для отображения и обработки.Моя текущая реализация работает просто отлично.Однако по разным причинам я пытаюсь переписать программу на C ++, используя объектно-ориентированный подход.
Текущая рабочая программа инициализировала 2-й поток следующим образом:
pthread_t netThread;
net = NetCom::initUdpRx(host,port);
pthread_create(&netThread, NULL, getNetSpike, (void *)NULL);
Здесьэто функция getNetSpike
, которая вызывается новым потоком:
void *getNetSpike(void *ptr){
while(true)
{
spike_net_t s;
NetCom::rxSpike(net, &s);
spikeBuff[writeIdx] = s;
writeIdx = incrementIdx(writeIdx);
nSpikes+=1;
totalSpikesRead++;
}
}
Теперь в моей новой OO-версии программы я настроил второй поток почти таким же образом:
void SpikePlot::initNetworkRxThread(){
pthread_t netThread;
net = NetCom::initUdpRx(host,port);
pthread_create(&netThread, NULL, networkThreadFunc, this);
}
Однако, поскольку pthead_create
принимает указатель на функцию void, а не указатель на метод-член объекта, мне нужно было создать эту простую функцию, которая обертывает
метод *1019*
void *networkThreadFunc(void *ptr){
SpikePlot *sp = reinterpret_cast<SpikePlot *>(ptr);
while(true)
{
sp->getNetworkSpikePacket();
}
}
, который затем вызываетметод getNetworkSpikePacket()
:
void SpikePlot::getNetworkSpikePacket(){
spike_net_t s;
NetCom::rxSpike(net, &s);
spikeBuff[writeIdx] = s; // <--- SegFault/BusError occurs on this line
writeIdx = incrementIdx(writeIdx);
nSpikes+=1;
totalSpikesRead++;
}
Код для двух реализаций почти идентичен, но 2-я реализация (версия OO) падает с SegFault или BusError после первого прочитанного пакета.Используя printf
, я сузил, какая строка вызывает ошибку:
spikeBuff[writeIdx] = s;
, и я не могу понять, почему это приводит к сбою моей программы.
Что я здесь не так делаю?
Обновление : я определяю spikeBuff
как закрытый член класса:
class SpikePlot{
private:
static int const MAX_SPIKE_BUFF_SIZE = 50;
spike_net_t spikeBuff[MAX_SPIKE_BUFF_SIZE];
....
}
Затем в конструкторе SpikePlot Iвызовите:
bzero(&spikeBuff, sizeof(spikeBuff));
и установите:
writeIdx =0;
Обновление 2 : Хорошо, что-то действительно странное происходит с моими индексными переменными.Чтобы проверить их работоспособность, я изменил getNetworkSpikePacket
на:
void TetrodePlot::getNetworkSpikePacket(){
printf("Before:writeIdx:%d nspikes:%d totSpike:%d\n", writeIdx, nSpikes, totalSpikesRead);
spike_net_t s;
NetCom::rxSpike(net, &s);
// spikeBuff[writeIdx] = s;
writeIdx++;// = incrementIdx(writeIdx);
// if (writeIdx>=MAX_SPIKE_BUFF_SIZE)
// writeIdx = 0;
nSpikes += 1;
totalSpikesRead += 1;
printf("After:writeIdx:%d nspikes:%d totSpike:%d\n\n", writeIdx, nSpikes, totalSpikesRead);
}
И я получаю следующий вывод на консоль:
Before:writeIdx:0 nspikes:0 totSpike:0
After:writeIdx:1 nspikes:32763 totSpike:2053729378
Before:writeIdx:1 nspikes:32763 totSpike:2053729378
After:writeIdx:1 nspikes:0 totSpike:1
Before:writeIdx:1 nspikes:0 totSpike:1
After:writeIdx:32768 nspikes:32768 totSpike:260289889
Before:writeIdx:32768 nspikes:32768 totSpike:260289889
After:writeIdx:32768 nspikes:32768 totSpike:260289890
Этот метод только метод, в котором я обновляю их значения (кроме конструктора, где я устанавливаю их в 0).Все остальные варианты использования этих переменных доступны только для чтения.