0

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;
    }
Ravi Vyas
  • 137
  • 1
  • 4
  • 19
  • 2
    the above code doesn't look like C++ – phuclv Apr 23 '15 at 03:19
  • 3
    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. – Jonathan Leffler Apr 23 '15 at 03:21
  • @LưuVĩnhPhúc the tag has been removed – Ravi Vyas Apr 23 '15 at 03:21
  • Duplicate http://stackoverflow.com/questions/8269048/length-of-array-in-function-argument – user3125367 Apr 23 '15 at 03:28

2 Answers2

2

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.

duncanc4
  • 1,191
  • 1
  • 9
  • 17
1

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).

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • Thanks for your answer, well to apply the lock functionality is one of the requirements of an assignment, hence I had to use it. – Ravi Vyas Apr 23 '15 at 03:51