Я разместил предыдущий вопрос "Seg Fault when using std::string on an embedded Linux platform", где я получил несколько полезных советов. С тех пор я отсутствовал в других проектах и недавно вернулся к рассмотрению этой проблемы.Потокобезопасный векторный и строковый контейнер?
Чтобы повторить, я ограничусь использованием кросс-компилятора arm-linux (версия 2.95.2), поскольку это то, что поставляется и поддерживается поставщиком встроенной платформы. Я понимаю, что проблема, скорее всего, связана с тем, что stdlib очень старый, и не особенно безопасный поток.
Проблема в том, что всякий раз, когда я использую контейнеры STL в нескольких потоках, я получаю ошибку сегментации. В приведенном ниже коде будет последовательно обнаружена ошибка, если я не буду использовать pthread_mutex_lock и операторы области действия вокруг объявлений контейнера (как и в других сообщениях).
Невозможно использовать этот подход в моем приложении, поскольку я передаю контейнеры различным методам и классам. Я бы идеально хотел решить эту проблему или найти подходящую альтернативу. Я пробовал стандартную библиотеку шаблонов STLPort и SGI с теми же результатами. Я могу только предположить, что, поскольку они связаны очень старым gcc, они не могут решить проблему.
Есть ли у кого-нибудь какие-либо возможные рекомендации или решения? Или, может быть, вы можете предложить реализацию вектора (и строки), который я могу вставить в свой код?
Заранее благодарим за любые указания.
#include <stdio.h>
#include <vector>
#include <list>
#include <string>
using namespace std;
/////////////////////////////////////////////////////////////////////////////
class TestSeg
{
static pthread_mutex_t _logLock;
public:
TestSeg()
{
}
~TestSeg()
{
}
static void* TestThread(void *arg)
{
int i = 0;
while (i++ < 10000)
{
printf("%d\n", i);
WriteBad("Function");
}
pthread_exit(NULL);
}
static void WriteBad(const char* sFunction)
{
//pthread_mutex_lock(&_logLock);
//{
printf("%s\n", sFunction);
string sKiller; // <----------------------------------Bad
//list<char> killer; // <----------------------------------Bad
//vector<char> killer; // <----------------------------------Bad
//}
//pthread_mutex_unlock(&_logLock);
return;
}
void RunTest()
{
int threads = 100;
pthread_t _rx_thread[threads];
for (int i = 0 ; i < threads ; i++)
{
pthread_create(&_rx_thread[i], NULL, TestThread, NULL);
}
for (int i = 0 ; i < threads ; i++)
{
pthread_join(_rx_thread[i], NULL);
}
}
};
pthread_mutex_t TestSeg::_logLock = PTHREAD_MUTEX_INITIALIZER;
int main(int argc, char *argv[])
{
TestSeg seg;
seg.RunTest();
pthread_exit(NULL);
}
Возможный дубликат [Threadsafe Vector class для C++] (http://stackoverflow.com/questions/1099513/threadsafe-vector-class-for-c) – Glen
Я в замешательстве - использование контейнеров выше полностью основанные на стеке (локальные переменные), поэтому сами контейнеры никогда не обращаются к потокам. И все-таки у вас все еще есть аварии? Это означает, что для простого создания контейнеров STL в стеке требуется синхронизация? Я никогда не слышал об этом ... –
Майк, это мои мысли, и почему это вызывает у меня такую головную боль. Я могу только предположить, что для некоторой оптимизации используются некоторые статические переменные, используемые в реализации, и именно это делает ее небезопасной. – Brad