嗨,我正在研究POSIX线程,我有像
这样的工作所以在我显示我的代码之前,我必须解释我所做的事情。首先,我有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);
}
}
答案 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等待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次。如果公共输出例程需要互斥锁,那么确定。
这不符合要求吗?