Results 1 to 1 of 1

Thread: pthread_cond_signal() and pthread_cond_wait() call hangs on ubuntu 18.04, 20.04

  1. #1
    Join Date
    Mar 2021
    Beans
    1

    Question pthread_cond_signal() and pthread_cond_wait() call hangs on ubuntu 18.04, 20.04

    Following application program executes successfully on Ubuntu 16.04.
    But a HANG condition is observed on Ubuntu 18.04, and Ubuntu 20.04.

    The application program contains two parts Sender and Receiver.

    Below are the steps to reproduce the problem.

    1. Execute the "Sender" application program with command "./Sender_Receiver Sender Init" on new terminal
    2. Observe prints on the terminal after every 5 seconds to confirm that Sender application is sending the signal
    3. Execute the "Receiver" application program with command "./Sender_Receiver Receiver" on new terminal
    4. Observe prints on the terminal after every 5 seconds to confirm that Receiver application is receiving the signal
    5. Terminate the "Receiver" application using (ctrl + c). This will terminate the Receiver application.
    6. Observe prints on the Sender terminal after every 5 seconds to confirm that Sender application still sending the signal and running
    7. Again Execute the "Receiver" application program with command "./Sender_Receiver Receiver" on terminal
    8. Observe prints on the Sender and Receiver terminals, The "Sender" and "Receiver" application will be observed in the HANG condition on Ubuntu 18.04, and Ubuntu 20.04.

    Note:- For the same steps, the application program works normally when executed on Ubuntu 16.04.

    Command used to build the code: gcc -g -Wall Sender_Receiver.cpp -o Sender_Receiver -L /lib -lrt -lpthread
    Command used to execute Sender application: ./Sender_Receiver Sender Init
    Command used to execute Receiver application: ./Sender_Receiver Receiver

    Can any one suggest the reason for the HANG condition on Ubuntu 18.04, and Ubuntu 20.04 with the probable solution.

    Code in the Sender_Receiver.cpp as below,

    Code:
    #include <stdio.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <unistd.h>
    #include <string.h>
    #include <time.h>
    #include <sys/mman.h>
    #include <sys/stat.h>        
    #include <fcntl.h>           
    #include <pthread.h>
    #include <cerrno>
    #include <sys/time.h>
    #include <limits.h>
    
    
    #define     SHM_DIR_PATH    "/dev/shm/"
    #define     ERROR            -1
    
    
    /* share memory access using MMAP */
    void mmap_wrapper(void** vppPtr, unsigned int uiMemorySize, char* cpMemoryName)
    {
        int iFdShm = ERROR;
        char cShmPath[NAME_MAX] = { 0 };
        int iRet = ERROR;
        void* vpMmapPtr = NULL;
    
        /* Sanity Check for pointer*/
        if(vppPtr == NULL)
        {
            printf("\nvppPtr Error");
        }
        /* Sanity Check memory size*/
        if(uiMemorySize < 1)
        {
            printf("\nuiMemorySize Error");
        }
        /* Sanity Check memory name pointer*/
        if(cpMemoryName == NULL)
        {
            printf("\ncpMemoryName Error");
        }
        /* Sanity Check memory name string size */
        if( (strlen(cpMemoryName) + strlen(SHM_DIR_PATH)) >= NAME_MAX)
        {
            printf("\ncpMemoryName Error");
        }
    
        /* Open share memory object */
        iFdShm = shm_open(cpMemoryName, O_CREAT | O_RDWR, ACCESSPERMS);
        if(iFdShm == ERROR)
        {
            printf("\nError during shm_open()");
            printf("\nError:%d: %s",errno, strerror(errno));
        }
    
        /* Create file name with particular path SHM_DIR_PATH*/
        strcpy(cShmPath, SHM_DIR_PATH);
        strcat(cShmPath, cpMemoryName);
    
        /* Change permission of the file*/
        iRet = chmod(cShmPath, ACCESSPERMS);
        if(iRet == ERROR)
        {
            printf("\nError during chmod()");
            printf("\nError:%d: %s",errno, strerror(errno));
        }
    
        /* truncate the file as per the required memory size */
        iRet = ftruncate(iFdShm, uiMemorySize);
        if(iRet == ERROR)
        {
            printf("\nError during ftruncate()");
            printf("\nError:%d: %s",errno, strerror(errno));
        }
    
        /* map the shared memory in the processes address space*/
        vpMmapPtr = mmap(0, uiMemorySize, PROT_WRITE, MAP_SHARED, iFdShm, 0);
        if(vpMmapPtr == MAP_FAILED)
        {
            printf("\nError during mmap()");
            printf("\nError:%d: %s",errno, strerror(errno));
        }
    
        /* close the file */
        iRet = close(iFdShm);
        if(iRet == ERROR)
        {
            printf("\nError during close()");
            printf("\nError:%d: %s",errno, strerror(errno));
        }
    
        /* return the shared memory pointer */
        (*vppPtr) = vpMmapPtr;
    }
    
    
    int main(int argc, char *argv[])
    {
        printf("\nExecuting_main");
    
        if( argc == 3 )
        {
           printf("\nThe argument supplied is %s\t%s\n", argv[1],argv[2]);
        }
        else if( argc == 2 )
        {
           printf("\nThe argument supplied is %s\n", argv[1]);
        }
        else if( argc > 3 )
        {
           printf("\nToo many arguments supplied.\n");
        }
        else
        {
           printf("\nOne argument expected.\n");
        }
    
        /* condition variable shared between Sender process and Receiver process */
        pthread_cond_t *shmVar;
        mmap_wrapper((void**)&shmVar, sizeof(pthread_cond_t),(char*)"shmVar");
    
        /* mutex shared between Sender process and Receiver process */
        pthread_mutex_t *shmVarMutex;
        mmap_wrapper((void**)&shmVarMutex, sizeof(pthread_mutex_t),(char*)"shmVarMutex");
    
        if(( argc == 3 ) && (strcmp(argv[2],"Init") == 0))
        {
            printf("\n%s::Init",argv[2]);
    
            pthread_condattr_t attr;
            pthread_condattr_init(&attr);
            pthread_condattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
            pthread_cond_init(shmVar, &attr);
    
            pthread_mutexattr_t attr1;
            pthread_mutexattr_init(&attr1);
            pthread_mutexattr_setpshared(&attr1, PTHREAD_PROCESS_SHARED);
            pthread_mutex_init(shmVarMutex, &attr1);
        }
    
        if(strcmp(argv[1],"Sender") == 0)
        {
            printf("\nSender::LoopStarting");
    
            while(1)
            {
                sleep(5);
                printf("\nSender::Locking");
                pthread_mutex_lock(shmVarMutex);
                printf("\nSender::Locked");
    
                printf("\nSender::Sending");
                pthread_cond_signal(shmVar);
                printf("\nSender::Sent");
    
                printf("\nSender::Unlocking");
                pthread_mutex_unlock(shmVarMutex);
                printf("\nSender::Unlocked");
            }
    
        }
    
        else if(strcmp(argv[1],"Receiver") == 0)
        {
            int iRet = ERROR;
            
            printf("\nReceiver::LoopStarting");
            while(1)
            {
    
                printf("\nReceiver::Locking");
                pthread_mutex_lock(shmVarMutex);
                printf("\nReceiver::Locked");
    
                printf("\nReceiver::Waiting");
                if((iRet = pthread_cond_wait(shmVar, shmVarMutex)) == 0)
                {
                    printf("\nReceiver::Received");
                }
    
                printf("\nReceiver::Unlocking");
                pthread_mutex_unlock(shmVarMutex);
                printf("\nReceiver::Unlocked");
            }
        }
        printf("\nExiting_main");
    }
    Attached Images Attached Images

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •