Самое надежное решение - заблокировать весь вектор для всех таких операций (что означает управление каждой операцией из любого места в коде, что действительно означает создание синхронизированного вектора).
Может быть, что-то простое, как это будет делать для ваших целей:
int append(std::vector<int>& numbers, int number){
int retval = numbers.size();
// what if some other thread calls push_back(number) in between these calls?
numbers.push_back(number);
int newSize = numbers.size();
//this bit is as a short-cut in common, easy, cases
if(newSize = retval + 1) //no need for further complication
return retval;
while(++retval < newSize)
if(numbers[retval] == number)
return retval;
//If we get this far, numbers have been deleted, not added. More discussion below.
}
Одна вещь об этом заключается в том, что если потоки выдвигают 3, 3, 3, 3, то возвращаемый индекс будет неправильным, хотя все равно будет индексом до 3. Это нормально или нет, зависит от ваших целей.
Другое - это то, что если вектор тем временем всплывает или иным образом укорачивается, то в лучшем случае мы добираемся до точки, в которой я просто помещаю комментарий в приведенном выше коде, в худшем случае - ошибки (так как они появляются снова после того, как мы получаем newSize и затем доступ к [retval] становится недействительным). Вам нужно подумать, может ли это случиться (возможно, вы знаете из остальной части кода, что этого никогда не произойдет) и что делать, если это произойдет.
Если ограничения этого слишком велики для вашего варианта использования, то боюсь, что создание полностью синхронизированного вектора - лучшее, о чем я могу думать.