打印字串(线程)的条件变量。

问题描述 投票:0回答:1

我有一个C线程程序,要反复打印下面的字串。

one two three one two three one two three...

我想测试一下如何用条件变量来完成这个任务 所以我使用了下面的代码。

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

pthread_cond_t c1 = PTHREAD_COND_INITIALIZER;
pthread_cond_t c2 = PTHREAD_COND_INITIALIZER;
pthread_cond_t c3 = PTHREAD_COND_INITIALIZER;

pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;

char arr[15] = "one";

void *printS(void *str)
{
    while(1)
    {
        pthread_mutex_lock(&m);

        if ( strcmp(arr,str) != 0)
        {
            if(strcmp("one",str) == 0)
            {
                pthread_cond_wait(&c1, &m);
            }
            else if(strcmp("two",str) == 0)
            {
                pthread_cond_wait(&c2, &m);
            }
            else if(strcmp("three",str) == 0)
            {
                pthread_cond_wait(&c3, &m);
            }

        }
        printf("%s  ", (char*)str);

        if (strcmp("one",arr) == 0)
        {
            strcpy(arr,"two");
            pthread_cond_signal(&c2);
        }
        else if (strcmp("two", arr) == 0)
        {
            strcpy(arr,"three");
            pthread_cond_signal(&c3);
        }
        else if (strcmp("three", arr) == 0)
        {
            strcpy(arr,"one");
            pthread_cond_signal(&c1);
        }
        pthread_mutex_unlock(&m);
    }
    return NULL;
}

int main()
{
    pthread_t t1, t2, t3;
    const char ch1[] = "one";
    const char ch2[] = "two";
    const char ch3[] = "three";

    pthread_mutex_init(&m,0);
    pthread_cond_init(&c1, 0);
    pthread_cond_init(&c2, 0);
    pthread_cond_init(&c3, 0);

    pthread_create(&t1, NULL, printS, (void *)ch1);
    pthread_create(&t2, NULL, printS, (void *)ch2);
    pthread_create(&t3, NULL, printS, (void *)ch3);

    pthread_join(t1, 0);
    pthread_join(t2, 0);
    pthread_join(t3, 0);

    while(1);
    return 0;
}

然而,用这段代码我得到了以下(不需要的)输出。

three three three three three three three one two three one two three one tho three three three three three three

我似乎找不到同步化或代码结构的问题。任何帮助都是感激不尽的,谢谢你!!

c string multithreading thread-synchronization
1个回答
0
投票

就像一般-评论里问的那样,你需要一个mutex,一个cv,就可以了。每个线程都已经得到了自己的谓词测试值。你所需要做的就是确保mutex被锁定(通过初始输入或通过从 pthread_cond_wait),并检查谓词状态,采取相应的行动。打印后,再改变谓词(字符串),在条件改变时广播其他线程,然后再循环。另外,mutex锁应该是在进入while-loop之前。cond-wait会根据需要解锁。

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

pthread_cond_t cv = PTHREAD_COND_INITIALIZER;
pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;

char arr[15] = "one";

void *printS(void *str)
{
    pthread_mutex_lock(&m);
    while(1)
    {
        // mutex is latched already
        while (strcmp(arr,str) != 0)
        {
            // this will unlatch the mutex and begin waiting on cv
            pthread_cond_wait(&cv, &m);
        }

        // mutex is once-again latched.
        printf("%s  ", (char*)str);

        // change string accordingly
        if (strcmp("one",arr) == 0)
            strcpy(arr,"two");

        else if (strcmp("two", arr) == 0)
            strcpy(arr,"three");

        else if (strcmp("three", arr) == 0)
            strcpy(arr,"one");

        // and tell everyone waiting something happened.
        // they will wake up as soon as we hit the next wait.
        pthread_cond_broadcast(&cv);
    }

    // will never be reached, but good form nonetheless.
    pthread_mutex_unlock(&m);
    return NULL;
}

int main()
{
    pthread_t t1, t2, t3;
    char ch1[] = "one";
    char ch2[] = "two";
    char ch3[] = "three";

    pthread_create(&t1, NULL, printS, ch1);
    pthread_create(&t2, NULL, printS, ch2);
    pthread_create(&t3, NULL, printS, ch3);

    pthread_join(t1, 0);
    pthread_join(t2, 0);
    pthread_join(t3, 0);

    fgetc(stdin);
    return 0;
}

© www.soinside.com 2019 - 2024. All rights reserved.