^Nisok^
9th January 2012, 21:49
Hey guys!
I have some major issues on the synchronisation of two threads. The problem is common producer - consumer but the speed of the two threads is variable and depends on an external device.
The producer is reading constantly datagrams from a UDPServer and after some validations it stores them to a boost::circular_buffer
producer ( QSemphore* freeBytes, QSemaphore * usedBytes, *BUFFER)
while(true)
{
if (udpSocket.waitForReadyRead(10) && !paused)
{
while (udpSocket.hasPendingDatagrams())
{
datagramSize = udpSocket.pendingDatagramSize();
datagram.resize(datagramSize);
udpSocket.readDatagram(datagram.data(), datagramSize);
hexDatagram.resize(datagramSize*2);
hexDatagramSize = hexDatagram.size();
hexDatagram = datagram.toHex();
blocksAcquired = datagramSize/1280;
READING_CHECKING();
if( OK_FILL_A_TEMP_BUFFER())
if(CERTAIN_AMOUNT_OF_INFORMATION)
{
freeBytes->acquire(1); // Pointer to a QSemaphore on the main thread
for (j=0; j<320; j++)
{
iBuffer->push_back(tempBuffer[j]);
}
tempIndex=0;
usedBytes->release(1);// Pointer to a QSemaphore on the main thread
}
}
datagram.clear();
hexDatagram.clear();
}
}
The consumer checks the usedBytes->available() in order to exceed a certain level and then start to process them.
while(true)
{
availablePacks = usedBytes->available();
if(availablePacks>20)
{
for(i=0; i<availablePacks-5; i++)
{
usedBytes->acquire(1);
for(j=0; j<80; j++)
{
cha[j] = iBuffer->front();
iBuffer->pop_front();
chb[j] = iBuffer->front();
iBuffer->pop_front();
chc[j] = iBuffer->front();
iBuffer->pop_front();
chd[j] = iBuffer->front();
iBuffer->pop_front();
}
//printf("Con: %d \n",iBuffer->size());
freeBytes->release(1);
for(j=0; j<80; j++)
{
PROCCESSING();
}
}
}
But all the time the consumer overruns the produces leading to a SIGSEVG error.
Added after 12 minutes:
I should also note that the BUFFER is 200 times larger than the transfering packages. and that I have only 100 Semaphores in order to ensure somehow that the threads won't overlap. Even if finally they do so.
I have some major issues on the synchronisation of two threads. The problem is common producer - consumer but the speed of the two threads is variable and depends on an external device.
The producer is reading constantly datagrams from a UDPServer and after some validations it stores them to a boost::circular_buffer
producer ( QSemphore* freeBytes, QSemaphore * usedBytes, *BUFFER)
while(true)
{
if (udpSocket.waitForReadyRead(10) && !paused)
{
while (udpSocket.hasPendingDatagrams())
{
datagramSize = udpSocket.pendingDatagramSize();
datagram.resize(datagramSize);
udpSocket.readDatagram(datagram.data(), datagramSize);
hexDatagram.resize(datagramSize*2);
hexDatagramSize = hexDatagram.size();
hexDatagram = datagram.toHex();
blocksAcquired = datagramSize/1280;
READING_CHECKING();
if( OK_FILL_A_TEMP_BUFFER())
if(CERTAIN_AMOUNT_OF_INFORMATION)
{
freeBytes->acquire(1); // Pointer to a QSemaphore on the main thread
for (j=0; j<320; j++)
{
iBuffer->push_back(tempBuffer[j]);
}
tempIndex=0;
usedBytes->release(1);// Pointer to a QSemaphore on the main thread
}
}
datagram.clear();
hexDatagram.clear();
}
}
The consumer checks the usedBytes->available() in order to exceed a certain level and then start to process them.
while(true)
{
availablePacks = usedBytes->available();
if(availablePacks>20)
{
for(i=0; i<availablePacks-5; i++)
{
usedBytes->acquire(1);
for(j=0; j<80; j++)
{
cha[j] = iBuffer->front();
iBuffer->pop_front();
chb[j] = iBuffer->front();
iBuffer->pop_front();
chc[j] = iBuffer->front();
iBuffer->pop_front();
chd[j] = iBuffer->front();
iBuffer->pop_front();
}
//printf("Con: %d \n",iBuffer->size());
freeBytes->release(1);
for(j=0; j<80; j++)
{
PROCCESSING();
}
}
}
But all the time the consumer overruns the produces leading to a SIGSEVG error.
Added after 12 minutes:
I should also note that the BUFFER is 200 times larger than the transfering packages. and that I have only 100 Semaphores in order to ensure somehow that the threads won't overlap. Even if finally they do so.