Ошибка сегментации при удалении существующего объекта - PullRequest
0 голосов
/ 26 августа 2011

Мой код имеет один поток, непрерывно обрабатывающий объекты, поставленные в очередь другими потоками.Объекты в очереди создаются с использованием «new» в функции, которая будет завершена, когда объект будет обработан.У меня нет проблем с этим, но удаление объекта.Должен ли я просто не удалять объект?Может быть, изменить способ передачи / создания этих объектов?

Object* myQueue[10];

function() {
    Object* myobject = new Object();
    queueObject(myobject);
}

queueObject(Object* object) {
    myQueue[index_x] = object;
    sem_post(&mySemaphore);
}


//// Thread 1
function();
...

//// Thread 2
handleObjects() {
    while(true) {
        sem_wait(&mySemaphore);
        // handle myQueue[index_x]
        delete myQueue[index_x]; ---> this produces Segmentation Fault
    }
}

(обработка index_x не опубликована для сокращения)

Ответы [ 2 ]

1 голос
/ 26 августа 2011

Полагаю, у вас есть состояние гонки.Какой механизм синхронизации вы используете для предотвращения изменения index_x обоими потоками?

Обычно рабочий поток должен вызвать sem_wait, изменить критические данные и затем вызвать sem_post.Я не могу предоставить 100% точный пример кода, не видя, как вы используете index_x, но он будет выглядеть примерно так:

queueObject(Object* object) {
    sem_wait(&mySemaphore);
    myQueue[index_x++] = object;
    sem_post(&mySemaphore);
}

handleObjects() {
    while(true) {
        sem_wait(&mySemaphore);
        // handle myQueue[index_x]
        delete myQueue[--index_x]
        sem_post(&mySemaphore);
    }
}

В настоящее время похоже, что у вас нет ничего, чтобы предотвратить изменение index_xв обоих потоках это может привести к тому, что index_x делает дурацкие вещи (не может увеличивать или уменьшать, что является самой распространенной дурацкой вещью). Здесь - статья в Википедии, объясняющая, что именно может пойти не так.

1 голос
/ 26 августа 2011

Добавьте несколько проверок вокруг удаления

 if ( myQueue[index] != 0 ) {
      delete myQueue[index];
      myQueue[index] = 0;
 } else {
      for diagnosis print large warning here - something is confused 
 }

, что приведет к двойному удалению через тот же индекс.Однако есть несколько других причин сбоя.Чтобы поймать их, нужны другие действия.

Подумайте:

  1. Есть ли вероятность состояния гонки?Могут ли два потока попытаться удалить по одному и тому же индексу?Вам нужно добавить синхронизацию?
  2. Возможно ли, чтобы один и тот же объект был добавлен в массив дважды, с разными индексами?В крайнем случае я мог бы добавить код, чтобы убедиться, что элемент еще не находится в массиве, прежде чем добавить его.
...