HELP! 关于deque迭代器及线程加锁有关问题

HELP! 关于deque迭代器及线程加锁问题
最近利用deque<string> g_r实现读者写者模型,一个线程函数只管压数据(.push_back()),另一个线程先判断deque中的数据是否多余50条,多余50条就用迭代器遍历50次并解引用塞到一个string变量里,然后封装格式通过一条Insert语句插入到数据库中。现在出现以下几个问题:

1.当运行到通过迭代器遍历数据的for语句时,进行条件判断时itera != g_r.begin()+50,出现deque iterators incompatible,去掉这个判断条件时,能通过这条语句;

2.在msg = *itera解引用时,出错:deque iterators not dereferable(之前没用迭代器,用.front()操作,也是这个错误),查阅资料后觉得应该是deque线程同步问题,故加锁,因为建项目时没加MFC库,故用内置临界区实现的:CRITICAL_SECTION g_cs;但貌似没起作用,现在困惑我的是怎么判断所加的线程保护机制是否起作用以及临界区加在哪(是循环还是单纯的语句?);

3.顺便问一下关于迭代器的问题:迭代器自增操作后值用%d输出其值为什么没变,但通过测试,迭代器自增后确实指向了下一个元素;C++primer上说:迭代器加减的数必须是size_type类型或者different_type类型,这个不太理解,我在1中所说的判断条件中直接加一个整形字面值行不行(反正顺序执行时是可以的)?还是必须要定义一个deque<string> size_type i = 50,然后itera != g_r.begin()+i?

注:以上问题在顺序执行的时候均不存在,即先压几百条数据,再判断、解引用、组合数据、插入数据库。下面是主要的代码。
[code=C/C++][/code]void DBModule::FullfillDQ()
{
string temp = "'219.245.89.29','239.255.255.250',1,'UDP',93,5778,TIMESTAMP '2012/1/25 11:00',TIMESTAMP '2012/2/18 20:00')";
EnterCriticalSection (&g_cs);
for (int i = 0; ; ++i)
{
g_r.push_back(temp);
TRACE("线程A:deque里压了%d条记录\n", i + 1);
Sleep(1);
}
  LeaveCriticalSection (&g_cs);
}
上面是压数据的线程函数



[code=C/C++][/code]
void DBModule::InsertDB()
{
int ID=1;
string temp, ltemp, values;
LinkDB();
TRACE("线程B:连接数据库成功\n");
while (1)
{
TRACE("线程B:单次循环开始,deque中记录数目:%d\n", g_r.size());
if (g_r.size()>=50)
{
  EnterCriticalSection (&g_cs);

for (deque<string>::iterator itera = g_r.begin(); itera != g_r.begin()+50; ++itera,++ID)
{

TRACE("线程B:%d---------------%d\n", ID, itera);
  msg = *itera;
TRACE("线程B:%d***************%d\n", ID, itera);

//下边这一坨(9行)都不用看,是我用来组装组合50条数据的
itoa(ID, temp_1, 10);
ltemp = temp_1;
temp_2 = "(" + ltemp + ",";
temp_2.append(msg);
temp_2 += ",";
values.append(temp_2);
memset(temp_1, 0, 1024);
temp_2.clear();
ltemp.clear();
}

  //遍历后pop50条数据  
for (deque<string>::size_type j = 0; j != 50; ++j)
{
TRACE("deque中的个数:%d\n", g_r.size());
g_r.pop_front();
}

TRACE("pop循环后deque中的个数:%d\n", g_r.size());

LeaveCriticalSection (&g_cs);

TRACE("线程B:50条数据组合成功\n");
   
  //下面这一坨(到结束)也不用看,是用来构造Insert语句的

//Remove the last character(,) of temp_2
values = values.substr(0, values.length()-1);

//Insert 50 VALUES through one INSERT language
values = "Insert into flowinfo(num,sip,dip,port,protocal,application,amount,begtime,endtime) VALUES" + values;
const char *order = values.c_str();
PQexec(conn, order);
TRACE("线程B:一次向数据库插入50条记录。单次循环结束\n");
values.clear();
}
}
}
以上是取数据插入数据库的线程函数

[code=C/C++][/code]
int _tmain(int argc, _TCHAR* argv[])
{
extern CRITICAL_SECTION g_cs;
InitializeCriticalSection(&g_cs);
DBModule database;
database.start_thread();
while(1);
return 0;
}
[code=C/C++][/code]
unsigned int _stdcall DBModule::threadInsertDB(void * pV)
{
DBModule *p = (DBModule *)pV;
p->InsertDB();
return 0;
}

unsigned int _stdcall DBModule::threadFullfillDQ(void * pV)
{
DBModule *p = (DBModule *)pV;
p->FullfillDQ();
return 0;
}

void DBModule::start_thread()
{
DBModule datebase;
_beginthreadex(0, 0, threadFullfillDQ, (void *)&datebase, 0, 0);