简体   繁体   English

如何在C编程中的子线程中使用互斥锁处理同步

[英]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. 但是,在打印输出后,应将代码重定向回子线程并等待用户按Enter键,一旦用户按Enter键,则应退出代码。 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. 这是可行的,但是我使用过sleep(),而我只想使用互斥锁,当我注释sleep()时,首先打印以下代码(“按Enter”),然后父代码打印实际输入。

/*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. sizeof(arg)返回4个字节的原因是,您要查询一个指针的大小,该大小将为4个字节。 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; 线程函数中arg的大小是指针的大小; apparently, you're using a 32-bit machine or a 32-bit build on a 64-bit machine. 显然,您正在使用32位计算机或64位计算机上的32位构建。 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). 该代码不会检查fgets()实际上返回了一行数据(错误)。

I'm not convinced that the lock is necessary at all. 我不认为完全没有必要锁定。 I'm not convinced the struct thread_data is worth keeping. 我不认为struct thread_data值得保留。 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). 您可能需要将其添加到结构中(或等效地,将缓冲区大小添加到您的结构中)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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