简体   繁体   中英

how to handle synchronization using mutex in a child thread in c programming

I am continuing with the Yesterday's help, and I have added another code in the child thread. Basically, when user enters a stdin, the child thread should read it and return it back to the parent thread. However, after printing the output, the code should be redirected back to the child thread and wait for the user to press enter, once the user press enter, the code should be exited. This is working, but I have used sleep() and I want to use only mutex(), when I comment the sleep(), then the following codes print first ("press enter") then the parent code prints actual input.

/*Required header files are added*/
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
/*this structure will hold the string of user input and the lock variable has created*/
struct thread_main
{
    char *buffer;
    char *bufferparent;
    pthread_mutex_t lock;
    pthread_mutex_t lock1;

} td;

/*it is a child thread, and store the user value in a buffer variable which has been declared in the thread_main structure*/


 static void *thread(void *buff)
    {
    /*the pointer has assigned to the structure, so we can get the values of a buffer array*/       
        struct thread_arguments *arg = buff;

        //the previous code

        pthread_mutex_unlock(&td.lock);
        pthread_mutex_destroy(&td.lock);

        sleep(1); // I want to ignore this.
        pthread_mutex_init(&td.lock, 0);
        pthread_mutex_lock(&td.lock);

        printf("press enter");
        /*this code will read buffer and check the enter*/

        pthread_mutex_unlock(&td.lock);
        pthread_mutex_destroy(&td.lock);

        return NULL;
    }

The reason sizeof(arg) is returning 4 bytes, is that you are asking for the size of a pointer, which will 4 bytes. You will need another way to tell the thread the length of your array.

As I noted in a comment:

The size of arg in the thread function is the size of a pointer; apparently, you're using a 32-bit machine or a 32-bit build on a 64-bit machine. You'll probably need to create a structure with the pointer and the size, and pass a pointer to that structure to the thread function.

This code works and illustrates what I mean:

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

struct thread_data
{
    char *buffer;
    pthread_mutex_t lock;
} td;

struct thread_arg
{
    char *buffer;
    size_t buflen;
};

static void *thread(void *data)
{
    struct thread_arg *arg = data;

    printf("%zd\n", arg->buflen);
    td.buffer = fgets(arg->buffer, arg->buflen, stdin);

    pthread_mutex_unlock(&td.lock);

    return NULL;
}

int main(void)
{
    char buffer[128];
    struct thread_arg arg = { buffer, sizeof(buffer) };
    pthread_t thread_id;

    pthread_mutex_init(&td.lock, 0);
    pthread_mutex_lock(&td.lock);
    printf("Enter Sync Command -- ");

    pthread_create(&thread_id, NULL, thread, &arg);

    pthread_mutex_lock(&td.lock);
    printf("message read by parent- %s", td.buffer);

    pthread_join(thread_id, NULL);

    pthread_mutex_unlock(&td.lock);
    pthread_mutex_destroy(&td.lock);
    return 0;
}

Note that you cannot use copies of locks as if they are the same as the original lock. The code doesn't check that fgets() actually returns a line of data (a bug).

I'm not convinced that the lock is necessary at all. I'm not convinced the struct thread_data is worth keeping. This code also works, relying on the thread exiting before the parent tries to read the buffer.

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

struct thread_arg
{
    char *buffer;
    size_t buflen;
};

static void *thread(void *data)
{
    struct thread_arg *arg = data;

    printf("%zd\n", arg->buflen);
    fgets(arg->buffer, arg->buflen, stdin);

    return NULL;
}

int main(void)
{
    char buffer[128];
    struct thread_arg arg = { buffer, sizeof(buffer) };
    pthread_t thread_id;

    printf("Enter Sync Command -- ");

    pthread_create(&thread_id, NULL, thread, &arg);
    pthread_join(thread_id, NULL);

    printf("message read by parent- %s", buffer);
    return 0;
}

If your code and synchronization get more complex, then the lock is a good idea. You might want to add it to the structure (or, equivalently, add the buffer size to your structure).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM