c - 如何在另一个线程完成工作之前挂起一个线程

标签 c multithreading pthreads posix

你好,我正在研究 POSIX 线程,我有一个类似的工作

  • 我们有 5 个线程,每个线程使用相同的函数分别打印 'a'、'b'、'c'、'd、'e'
  • 话题必须按字母顺序创建。
  • 每个字符必须在屏幕上打印 50 次
  • 'a'只有在'c'全部打印完后才能打印
  • 'b'只有在'd'全部打印完后才能打印
  • 'c'只有在'd'全部打印完后才能打印

所以在我展示我的代码之前,我必须解释我做了什么。首先,我有 5 个全局变量(它们是标志,它们最初都设置为 1),我将它们分配给 pthread_create() 函数返回的值。然后在主函数中,我在加入线程之前使用了 if() 条件。但我想我正在尝试错误的方式。问题是我无法处理“在 thread_a 之前,thread_d 必须完成其工作”的过程。如果您能提供帮助并提出一些更好的想法,我将不胜感激。这是我的代码,

#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>

int counter = 0;

int flag_a = 1;
int flag_b = 1;
int flag_c = 1;
int flag_d = 1;
int flag_e = 1;

pthread_mutex_t mymutex=PTHREAD_MUTEX_INITIALIZER;

void* thread_function(void* str);
void print_char(char* ch);

int main(){

    pthread_t thread_a, thread_b, thread_c, thread_d, thread_e;

    char* a = "a";
    char* b = "b";
    char* c = "c";
    char* d = "d";
    char* e = "e";


    flag_a = pthread_create( &thread_a, NULL, thread_function, (void*) a );
    flag_b = pthread_create( &thread_b, NULL, thread_function, (void*) b );
    flag_c = pthread_create( &thread_c, NULL, thread_function, (void*) c );
    flag_d = pthread_create( &thread_d, NULL, thread_function, (void*) d );
    flag_e = pthread_create( &thread_e, NULL, thread_function, (void*) e );

    if(flag_c==0)
        pthread_join( thread_a, NULL );

    pthread_join( thread_b, NULL );

    if(flag_d==0)
        pthread_join( thread_c, NULL );

    if(flag_d==0)
        pthread_join( thread_d, NULL );

    pthread_join( thread_e, NULL );

    printf("\nCounter = %d\n", counter);

    return 0;
}

void* thread_function(void* str) {

    int i;
    char* msg = (char*) str;

        for(i=0; i<50; i++) {

            pthread_mutex_lock(&mymutex);
            counter++;  
            print_char(msg);
            pthread_mutex_unlock(&mymutex);

        }
    }

void print_char(char* ch){

    int i;

    for(i=0; i<1; i++) {
        printf("%s --> ", ch);
        fflush(stdout);
        sleep(1);
    }
}

编辑:我找到了一个可以正确打印字符的解决方案,但问题是我无法异步打印它们。我的意思是每当我运行代码时,它都有相同的输出:

e-->d-->c-->b-->a(每个字符打印50次)

这是 thread_function() 的编辑部分

void* thread_function(void* str) {

    int i;
    char* msg = (char*) str;

        while( (strcmp(msg,"a") == 0) && (counter_c < 5) ){
        ;;
    }

        while( (strcmp(msg,"c") == 0) && (counter_d < 5) ){
        ;;
    }

        while( (strcmp(msg,"b") == 0) && (counter_d < 5) ){
        ;;
    }

        for(i=0; i<5; i++) {

            pthread_mutex_lock(&mymutex);               
            counter++;

                if( strcmp(msg,"d") == 0 )
                    counter_d++;

                if( strcmp(msg,"c") == 0 )
                    counter_c++;

            print_char(msg);
            pthread_mutex_unlock(&mymutex);

        }
    }

最佳答案

从逻辑上讲,您有一个依赖关系图,您需要为每个线程提供一种方法:a) 在开始打印之前等待某些条件发生,以及 b) 发出已完成打印的信号,以便其他线程等待的线程可以启动。在 pthreads 中,这可以通过条件变量来完成。所以你可以做什么,而不是传递一个指向要打印的字符的指针,而是传递一个指向包含要打印的字符的结构的指针,一个在开始打印之前要等待的条件变量(和关联的互斥锁),以及另一个条件变量关联的互斥锁在完成时发出信号。然后在主线程中,在创建线程之前,您当然需要适本地设置所有这些结构,并且在创建线程之后,主线程应该向那些位于末尾(或开始,取决于您如何看看它..) 的依赖链,以便开始整个过程​​。

有关如何使用条件变量的介绍,请参见例如https://computing.llnl.gov/tutorials/pthreads/#ConditionVariables

关于c - 如何在另一个线程完成工作之前挂起一个线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12762411/

相关文章:

c - 反白显示消息

python - 将 POST 从请求转换为 GAE urlfetch

java - 如何测试一个线程是否是 Java 中唯一剩余的线程?

c - 在 C 中的 pthread 函数中传递一个 int 数组

c++ - 测量相互依赖线程的并行计算时间

c++ - 生产者、消费者和我可爱的僵局

c - 计算矩阵逆的问题

c++ - 在 WINAPI 中格式化写入文件

c - setsocketoptions L2CAP_OPTIONS 失败并显示 "Invalid argument error"

c# - 如果我只想以线程安全的方式测试和设置标志,那么线程类是什么?