Bogdan - Petru Ungureanu

  Home  |   Contact  |   Syndication    |   Login
  1 Posts | 0 Stories | 1 Comments | 0 Trackbacks

News

As soon as my laptop will be fixed or I'll buy new components for my desktop PC, I'll post an entry about emulating an RS232-RS485 connection in C#.

Archives

Post Categories

Saturday, May 24, 2008 #

Hi there, people. My first post is inspired by my new experience with QNX and generally with programming processes and threads using POSIX standards.
The idea is simple: it uses 3 processes, 2 anonymous pipes and a mutex; in the child processes you calculate the sum and respectively the product of the given numbers and print the results in a file, controlling the access with the mutex. So the child process 1 does 1+...+n and the child process 2 does n!
Everything goes perfect except destroying the mutex. I get EINVAL code error every time I try to destroy the mutex. More, printing the pointer of the owner (eg. (void*)mymutex.owner) I get the 0x000... address code. Even more, it's not clear for me how can I further access other members of the owner structure, as I haven't found anywhere in the specs details about this. I'm pretty sure 0x0000... means invalid owner, but I'd need some confirmation. I'll try dig this one and post the correct solution.
So here is the code...

#include <unistd.h>
#include <pthread.h>
#include <stdio.h>
#include <errno.h>

int main()

{
    pid_t pid1,pid2;
    int readvalue,i,mypipe1[2],mypipe2[2];
    float temp;
    pthread_mutex_t mymutex;
    FILE* f;

    if((f=fopen("results.txt","wt"))==NULL)
    {
        printf("Error creating the output file\n");
        exit(0);
    }

    switch(pthread_mutex_init(&mymutex,NULL))
    {
    case EAGAIN:
        printf("Insufficient resources to create mutex\n");
        exit(0);
        break;
    case EBUSY:
        printf("Mutex already initialized\n");
        exit(0);
        break;
    case EFAULT:
        printf("Error initializing mutex\n");
        exit(0);
        break;
    default:
        break;
    }

    if(pipe(mypipe1)==-1)
    {
        printf("Error creating the anonymous pipe 1\n");
        exit(0);
    }

    if(pipe(mypipe2)==-1)
    {
        printf("Error creating the anonymous pipe 2\n");
        exit(0);
    }

    if(pid1==0)
    {
        close(mypipe1[1]);
        printf("Child process number 1\n");
        readvalue=1;
        while(readvalue>0)
        {
            read(mypipe1[0],&readvalue,sizeof(int));
            temp=0;
            if(readvalue>0)
            {
                for(i=1;i<=readvalue;i++)
                    temp+=i;

                switch(pthread_mutex_lock(&mymutex))
                {
                case EAGAIN:
                    printf("Insufficient resources to lock mutex in child process number 1\n");
                    exit(0);
                    break;
                case EDEADLK:
                    printf("Reached a deadlock trying to lock mutex in child process number 1\n");
                    exit(0);
                    break;
                case EINVAL:
                    printf("Mutex suggested is invalid in child process number 1\n");
                    exit(0);
                    break;
                default:
                    fprintf(f,"The sum of the numbers between 0 and %d is %f\n",readvalue,temp);
                    fflush(f);

                    switch(pthread_mutex_unlock(&mymutex))
                    {
                    case EPERM:
                        printf("The process child 1 doesn't own the mutex\n");
                        exit(0);
                        break;
                    case EINVAL:
                        printf("Mutex suggested is invalid in child process number 1\n");
                        exit(0);
                        break;
                    default: break;
                    }
                    break;
                }
            }
        }
        close(mypipe1[0]);
        printf("Child process number 1 will exit...\n");
    }
    else
    {
        if((pid2=fork())<0)
        {
            printf("Error creating child process number 2\n");
            exit(0);
        }

        if(pid2==0)
        {
            close(mypipe2[1]);
            printf("Child process number 2\n");
            readvalue=1;
            while(readvalue>0)
            {
                read(mypipe2[0],&readvalue,sizeof(int));
                temp=1;
                if(readvalue>0)
                {
                    for(i=1;i<=readvalue;i++)
                        temp*=i;

                    switch(pthread_mutex_lock(&mymutex))
                    {
                    case EAGAIN:
                        printf("Insufficient resources to lock mutex in child process number 2\n");
                        exit(0);
                        break;
                    case EDEADLK:
                        printf("Reached a deadlock trying to lock mutex in child process number 2\n");
                        exit(0);
                        break;
                    case EINVAL:
                        printf("Mutex suggested is invalid in child process number 2\n");
                        exit(0);
                        break;
                    default:
                        fprintf(f,"The product of the numbers between 1 and %d is %f\n",readvalue,temp);
                        fflush(f);

                        switch(pthread_mutex_unlock(&mymutex))
                        {
                        case EPERM:
                            printf("The process child 1 doesn't own the mutex\n");
                            exit(0);
                            break;
                        case EINVAL:
                            printf("Mutex suggested is invalid in child process number 1\n");
                            exit(0);
                            break;
                        default: break;
                        }
                        break;
                    }
                }
            }
            close(mypipe2[0]);
            printf("Child process number 2 will exit...\n");
        }
        else
        {
            printf("Parent process\n");
            close(mypipe1[0]);
            close(mypipe2[0]);
            printf("Insert numbers...\n");
            readvalue=1;
            while(readvalue>0)
            {
                scanf("%d",&readvalue);
                write(mypipe1[1],&readvalue,sizeof(int));
                write(mypipe2[1],&readvalue,sizeof(int));
            }
            close(mypipe1[1]);
            close(mypipe2[1]);
            printf("Parent process will exit...\n");
        }
    }
    if(fclose(f)<0)
    {
        printf("Error closing the output file\n");
        exit(0);
    }

    switch(pthread_mutex_destroy(&mymutex))
    {
    case EBUSY:
        printf("Mutex is blocked cannot be destroyed\n");
        exit(0);
        break;
    case EINVAL:
        printf("Mutex is invalid while trying to destroy it\n");
        exit(0);
        break;
    default:
        break;
    }
    return 0;
}