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

时间:2012-10-06 18:06:11

标签: c multithreading pthreads posix

嗨,我正在研究POSIX线程,我有像

这样的工作
  • 我们有5个主题,每个主题分别使用相同的功能打印'a','b','c','d,'e'
  • 必须按字母顺序创建线程。
  • 每个角色必须在屏幕上打印50次
  • 'a'只能在所有'c'打印后打印
  • 'b'只能在打印完所有内容后打印
  • 'c'只能在打印完所有后打印

所以在我显示我的代码之前,我必须解释我所做的事情。首先,我有5个全局变量(它们是标志,所有变量都设置为1)并且我将它们分配给pthread_create()函数返回的值。然后在我加入线程之前使用if()条件的main函数中。但我想我正在尝试错误的方式。问题是我必须处理“在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 - &gt; d - &gt; c - &gt; b - &gt; 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);

        }
    }

4 个答案:

答案 0 :(得分:1)

逻辑上,你有一个依赖图,你需要一种方法让每个线程a)等待一些条件发生才能开始打印它的东西,b)发出信号表明它已完成打印,以便其他线程等待可以开始。在pthreads中,可以使用条件变量来完成。那么你可以做什么,而不是传递一个指向要打印的字符的指针,将指针传递给包含要打印的字符的结构,一个条件变量(和相关的互斥锁)在开始打印之前等待,另一个条件变量与关联的互斥锁完成后发出信号。然后在主线程中,在创建线程之前,你当然需要适当地设置所有这些结构,并且在创建线程之后,主线程应该发出最后(或开始,取决于你如何)的条件变量的信号看看它的依赖链,以便让整个过程开始。

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

答案 1 :(得分:1)

//首先打印d然后在c完成后打印b或c它将打印a.then main函数将等待

#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_d = pthread_create( &thread_d, NULL, thread_function, (void*) d );
        pthread_join( thread_d, NULL );
    flag_b = pthread_create( &thread_b, NULL, thread_function, (void*) b );
    flag_c = pthread_create( &thread_c, NULL, thread_function, (void*) c );

  pthread_join( thread_c, NULL );

    flag_a = pthread_create( &thread_a, NULL, thread_function, (void*) a );
    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);
pthread_exit(NULL);  //or you can join thread e before printf() statement 
    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);
    }
}

答案 2 :(得分:0)

实际上你想要的是在开始工作之前暂停线程,直到给定的线程完成。

  • 主题A:打印A
  • 主题B:打印B
  • 主题C:打印C
  • 线程D:打印D's

在你的情况下,你希望A等待C,B和C等待D并启动D.为此你需要semaphores,因为信号量会阻塞线程直到它被注意到唤醒

答案 3 :(得分:0)

也许我误解了这个要求?伪:

Start Ethread('e'); // can run async, since no contraints on 'e'
Start Dthread('d'); // print 'd' and 
Join Dthread;       // wait for 'd' to finish
Start Bthread('b'); // now start on the 'b'
Start Cthread('c'); // and the 'c'
Join Cthread;       // but just wait for the 'c' to finish
Start Athread('a'); // and then print the 'a'

每个线程将其传递的char打印50次。如果公共输出例程需要互斥锁,那么确定。

这不符合要求吗?