这些线程中的每一个是否都等到互斥锁解锁后才执行功能?

Do each one of these threads wait until the mutex is unlocked to perform a function?

下面是我的系统 class 中的互斥锁程序。它为输入字符串中的每个字母创建一个新线程,然后将每隔一个字母转换为大写。 我的问题是,c 中的线程实际上 "wait" 是否会在执行功能之前解锁互斥体?或者,如果方法被锁定,它们是否会导致操作失败?

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

#define SIZE 50

char sentence[2000];
int  ind = 0;

pthread_mutex_t count_mutex;

void
increment_ind()
{
    ind = ind + 1;    
}

char convertUppercase(char lower)
{
    //Converts lowercase un uppercase
    if ((lower > 96) && (lower < 123))
        return (lower - 32);
    else
        return lower;
}

void printChar()
{
    //prints the converted sentence
    printf("The new sentence is [%d]: \t%c\n", ind, sentence[ind]);
    increment_ind();
}

void *convertMessage(void *ptr)
{
    pthread_mutex_lock(&count_mutex);   

    // Function that each threads initiates its execution
    char aux;

    if (ind % 2)
        sentence[ind] = convertUppercase(sentence[ind]);

    printChar();
    pthread_mutex_unlock(&count_mutex);
    return 0;
}

int main()
{
    int i;
    char buffer[SIZE];
    char *p;
    pthread_t ts[SIZE]; // define up to 50 threads

    printf("Please enter a phrase (less than 50 characters): ");

    if (fgets(buffer, sizeof(buffer), stdin) != NULL_
        if ((p = strchr(buffer, '\n')) != NULL)
            *p = '[=10=]';

    strcpy(sentence, buffer);
    printf("The original sentence is: \t %s\n", sentence);

    // create one thread for each character on the input word
    for(i = 0; i < strlen(buffer) + 1; ++i)
        pthread_create(&ts[i], NULL, convertMessage, NULL);

    // we wait until all threads finish execution
    for(i = 0; i < strlen(buffer); i++)
        pthread_join(ts[i], NULL);

    printf("\n");

    return 0;
}

来自POSIX documentation

The mutex object referenced by mutex shall be locked by a call to pthread_mutex_lock() that returns zero or [EOWNERDEAD]. If the mutex is already locked by another thread, the calling thread shall block until the mutex becomes available. This operation shall return with the mutex object referenced by mutex in the locked state with the calling thread as its owner.

(强调我的)

所以,是的,线程 "waits" 使互斥体可用(除非发生错误)。当pthread_mutex_lock()returns时,调用线程已经获得了锁。但它也可能 return 有错误。这就是为什么您应该检查 return 值。

是的,线程通常会等待互斥锁可用,但您的线程不会。我假设你问这个问题的原因是你的线程都忽略了互斥锁。他们出现的原因是 main() 你忘了打电话:

pthread_mutex_init(&count_mutex, NULL);

更糟糕的是,您忘记检查 return 值:

pthread_mutex_lock(&count_mutex);

由于未初始化的互斥体,它正在吐出错误代码 22!

下面是我对您的代码进行的修改以解决上述问题,修复其他错误(您启动的线程比加入的线程多等),以及一些样式调整:

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

#define SIZE 50

char sentence[2000];
int ind = 0;

pthread_mutex_t count_mutex;

void increment_ind()
{
    ind = ind + 1;
}

char convertUppercase(char character)
{
    // Converts lowercase to uppercase
    if (character >= 'a' && character <= 'z')
    {
        character -= ' ';
    }

    return character;
}

void printSentence()
{
    // prints the converted sentence
    printf("The new sentence is [%d]: %s\n", ind, sentence);
}

void *convertMessage(void *pointer)
{
    if (pthread_mutex_lock(&count_mutex) == 0)
    {
        // Function that each threads initiates its execution
        if (ind % 2 == 1)
        {
            sentence[ind] = convertUppercase(sentence[ind]);
        }

        printSentence();

        increment_ind();

        (void) pthread_mutex_unlock(&count_mutex);
    }
    else
    {
        /* handle the error! */
    }

    return NULL;
}

int main()
{
    char *p, buffer[SIZE];
    pthread_t threads[SIZE]; // define up to 50 threads

    (void) pthread_mutex_init(&count_mutex, NULL);

    printf("Please enter a phrase (less than 50 characters): ");

    if (fgets(buffer, sizeof(buffer), stdin) == NULL)
    {
        /* print an error message to stderr */
        return 1;
    }

    if ((p = strchr(buffer, '\n')) != NULL)
    {
        *p = '[=12=]';
    }

    (void) strcpy(sentence, buffer); // copy local string to global string

    printf("The original sentence is: %s\n", sentence);

    // create one thread for each character in the input string
    for (int i = 0; i < strlen(buffer); i++)
    {
        (void) pthread_create(&threads[i], NULL, convertMessage, NULL);
    }

    // we wait until all threads finish execution
    for (int i = 0; i < strlen(buffer); i++)
    {
        (void) pthread_join(threads[i], NULL);
    }

    printf("\n");

    return 0;
}