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

时间:2016-10-19 17:33:15

标签: c multithreading mutex

以下是我系统类的互斥锁程序。它为输入字符串中的每个字母创建一个新线程,然后将每个其他字母转换为大写字母。 我的问题是,在执行函数之前,c中的线程是否实际上“等待”互斥锁解锁?或者如果方法被锁定,他们只是失败了吗?

#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 = '\0';

    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;
}

2 个答案:

答案 0 :(得分:1)

来自POSIX documentation

  

互斥引用的互斥对象应通过调用来锁定   pthread_mutex_lock()返回零或[EOWNERDEAD]。 如果是互斥量   已经被另一个线程锁定,调用线程将被阻塞   直到互斥锁变为可用。此操作将返回   mutex在锁定状态下引用的互斥对象   将线程称为其所有者。

(强调我的)

所以,是的,线程&#34;等待&#34;使互斥锁可用(除非发生错误)。当pthread_mutex_lock()返回时,调用线程已获得锁定。但它也可能会带来错误。这就是你应该检查返回值的原因。

答案 1 :(得分:1)

是的,一般情况下线程都会等待互斥锁可用,但不是你的。我假设你问这个问题的原因是你的线程都忽略了互斥量。他们的原因在于main()你忘记打电话了:

pthread_mutex_init(&count_mutex, NULL);

更糟糕的是,你忘记检查返回值:

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 = '\0';
    }

    (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;
}