我尝试将 OpenMP 中的parallel execution of sections
翻译为 pthread 计划。我使用全局变量(sect_left
)来记录要执行的节的总数,但似乎不同线程中的变体(sect_left
)是两个不同的变体并且具有独立的值。
为了使我的程序更容易理解,我已将其简化,如下所示:
#include <pthread.h>
define get_tid() syscall(__NR_gettid)
int sect_left = -1; //the total number of sections to be execute
int nthr_in_sect = 0; //the number of threads entered the sections
pthread_mutex_t mt_sect;
void entering_sections(int numberofsections)
{
pthread_mutex_lock(&mt_sect);
if(nthr_in_sect <= 0){ //if this is the first thread come in
sect_left = numberofsections; //set number of sections when first thread come in
printf("%d set number of sections: %d\n", get_tid(), sect_left);
}
nthr_in_sect++; //the number of threads entered +1
pthread_mutex_unlock(&mt_sect);
}
void leaving_sections()
{
pthread_mutex_lock(&mt_sect);
nthr_in_sect--; //the number of threads in sections -1 after leaving sections
pthread_mutex_unlock(&mt_sect);
}
int get_section()
{
if (sect_left < 0) return (-1);
pthread_mutex_lock(&mt_sect);
int s = --(sect_left); //fetch a section and the total number -1
pthread_mutex_unlock(&mt_sect);
return (s);
}
static void * func(void *arg)
{
{
int caseid = -1;
entering_sections(2);
for(;;)
{
//if there is no section remain
if((caseid = get_section()) < 0) break;
switch(caseid)
{
case 0:
printf("section 11 threadID = %d\n",get_tid());
break;
case 1:
printf("section 22 threadID = %d\n",get_tid());
break;
}
}
leaving_sections();
}
}
void main()
{
pthread_mutex_init(&mt_sect, NULL);
pthread_t thr;
pthread_create(&thr,NULL,func, (void *) 0);
(*func)((void *) 0);
pthread_join(thr,NULL);
pthread_mutex_destroy(&mt_sect);
}
我的程序输出是:
如果不同线程中的全局变体是不同的变体,如何表示整个程序中唯一的变体,无论有多少线程?
谢谢!
答案 0 :(得分:1)
我认为以下情况正在发生:
nthr_in_sect == 0
4789: entering_sections(2);
sec_left = 2
4789: print section strings
sec_left = -1
4789: leaving_sections();
nthr_in_sect == 0 (again)
4790: entering_sections(2);
sec_left = 2
4790: print section strings
sec_left = -1
4790: leaving_sections();
nthr_in_sect == 0 (again)
所以程序的功能如同编写。第一个线程刚刚完成,第二个线程重新开始,因为它认为它是第一个。
也许你应该为nthr_entered_sect和nthr_left_sect设置单独的计数器?或者布尔标志sec_left_initialized。