Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Problem with using QSystemSemaphore under the Ubuntu OS



  • Hello!
    ,There is the simplest implementation of a producer-consumer template using QSharedMemory and two QSystemSemaphore templates. After a fixed number of iterations, an error occurs: "code = 5, error = QSystemSemaphore::modifySemaphore: out of resources". The code sample below. What could be the problem? My code? In the QSystemSemaphore implementation(the error appears on the Ubuntu 18.04, but not on the Windows 10 )? In the operating system settings? Qt=5.12.5
    Thanks in advance!
    Producer:

    // producer
    #include <QCoreApplication>
    #include <QDebug>
    #include <QSharedMemory>
    #include <QString>
    #include <QSystemSemaphore>
    
    #include <iostream>
    #include <unistd.h>
    
    const long int DataSize = 1000000;
    
    const int BufferSize = 8192;
    const QString sharedMemoryKey = "MAVERICK-TEST";
    const QString freeSemKey = "FreeBytesSemaphore";
    const QString usedSemKey = "UsedBytesSemaphore";
    
    int main(int argc, char* argv[])
    {
      QCoreApplication a(argc, argv);
      QSharedMemory sharedMem(sharedMemoryKey);
    
    #ifndef Q_OS_WIN
      if (sharedMem.attach())
        sharedMem.detach();
    #endif
    
      bool result = sharedMem.create(BufferSize);
    
      if (!result)
      {
        qInfo() << qUtf8Printable(QString("Shared memory creation failed. Error code(%1): %2")
                                    .arg(sharedMem.error())
                                    .arg(sharedMem.errorString()));
        return EXIT_FAILURE;
      }
    
      qInfo() << "Shared memory object created";
    
      QSystemSemaphore freeSem(freeSemKey, BufferSize, QSystemSemaphore::Create);
      QSystemSemaphore usedSem(usedSemKey, 0, QSystemSemaphore::Create);
    
      for (auto i = 0; i < DataSize; ++i)
      {
        if (!freeSem.acquire())
        {
          std::cout << qUtf8Printable("Can't acquire semaphore") << std::endl;
          QString error =
            QString("code = %1, error = %2").arg(freeSem.error()).arg(freeSem.errorString());
          std::cout << qUtf8Printable(error);
          throw(std::runtime_error(error.toStdString()));
        }
        char data = "ACGT"[(int)qrand() % 4];
    
        ::memcpy(((char*)sharedMem.data()) + (i % BufferSize), &data, sizeof(char));
        static int count = 0;
        std::cout << QString("produced = %1, value = %2").arg(count++).arg(data).toStdString()
                  << std::endl;
        if (!usedSem.release())
        {
          std::cout << qUtf8Printable("Can't release semaphore") << std::endl;
          QString error =
            QString("code = %1, error = %2").arg(usedSem.error()).arg(usedSem.errorString());
          std::cout << qUtf8Printable(error);
          throw(std::runtime_error(error.toStdString()));
        }
        usleep(1000);
      }
    
      sleep(2); // wait consumer process, TOTO: fix it
      return 0;
    }
    

    Consumer:

    #include <QCoreApplication>
    #include <QDebug>
    #include <QSharedMemory>
    #include <QString>
    #include <QSystemSemaphore>
    #include <QTime>
    
    #include <iostream>
    #include <unistd.h>
    
    const long int DataSize = 1000000;
    
    const int BufferSize = 8192;
    const QString sharedMemoryKey = "MAVERICK-TEST";
    const QString freeSemKey = "FreeBytesSemaphore";
    const QString usedSemKey = "UsedBytesSemaphore";
    
    int main(int argc, char* argv[])
    {
      QCoreApplication a(argc, argv);
      QSharedMemory sharedMem(sharedMemoryKey);
      QSystemSemaphore freeSem(freeSemKey);
      QSystemSemaphore usedSem(usedSemKey);
    
      sharedMem.attach();
      if (!sharedMem.isAttached())
      {
        qInfo() << qUtf8Printable(QString("Shared memory attachion failed. Error code(%1): %2")
                                    .arg(sharedMem.error())
                                    .arg(sharedMem.errorString()));
        return EXIT_FAILURE;
      }
    
      qInfo() << "Shared memory object attached";
    
      for (auto i = 0; i < DataSize; ++i)
      {
        if (!usedSem.acquire())
        {
          std::cout << qUtf8Printable("Can't acquire semaphore") << std::endl;
          QString error =
            QString("code = %1, error = %2").arg(usedSem.error()).arg(usedSem.errorString());
          std::cout << qUtf8Printable(error);
          throw(std::runtime_error(error.toStdString()));
        }
    
        char* res = ((char*)sharedMem.data() + i % BufferSize);
        static int count = 0;
        std::cout << QString("consumed = %1, value = %2").arg(count++).arg(res[0]).toStdString()
                  << std::endl;
    
        if (!freeSem.release())
        {
          std::cout << qUtf8Printable("Can't release semaphore") << std::endl;
          QString error =
            QString("code = %1, error = %2").arg(freeSem.error()).arg(freeSem.errorString());
          std::cout << qUtf8Printable(error);
          throw(std::runtime_error(error.toStdString()));
        }
        usleep(1000);
      }
    
      return 0;
    }
    
    


  • The problem is most likely related to this error:
    https://bugreports.qt.io/browse/QTBUG-8497


Log in to reply