49 个线程的线程屏障

Thread barrier for 49 threads

我应该在某个进程中创建49个线程(我的问题这里有多个进程,所以我们称进程为P3)。我已经创建了这些线程,但问题出现在这里:在任何时候,最多允许 5 个线程在 P3 中 运行,而不计算主进程。只有当总共有 5 个线程 运行ning 时,P3 中的线程 13 才允许结束(线程 13 在这 5 个线程中)。我的问题是:我如何确保在程序执行的某个时刻会有 5 个线程 运行ning,其中会有线程 13 以便它可以结束它的执行。我使用 C 作为编程语言和 Linux 系统调用。此外,我不允许使用 "sleep()" 和 "usleep()".

这是我计算线程数的函数。

` void* thread_function2(void* arg) {

TH_STRUCT* st=(TH_STRUCT*)arg;



sem_wait(&sem);

sem_wait(&sem2);
nrThreads++;
sem_post(&sem2);

printf("Number of threads running: %d\n",nrThreads);




sem_wait(&sem3);
nrThreads--;
sem_post(&sem3);

sem_post(&sem);

return 0;

}`

这部分来自我创建线程的主线程: sem_init(&sem,0,5); sem_init(&sem2,0,1); sem_init(&sem3,0,1); sem_init(&sem4,0,1);

        for(int i=1;i<=49;i++)
        {
            params1[i].procNum=3;
            params1[i].threadNum=i;
            pthread_create(&tids1[i],NULL,thread_function2,&params1[i]);
        }

`

开始一个线程是通过打印单词 BEGIn 和线程号的函数信息 (args) 完成的。
结束一个线程是通过一个函数 info(args) 来完成的,它打印出单词 END 和线程号。
这是一个输出示例,以及线程在开始和结束时执行的操作:

[ ] BEGIN P5 T0 pid=30059 ppid=30009 tid=-99981504  
[ ]  END  P5 T0 pid=30059 ppid=30009 tid=-99981504  
[ ] BEGIN P6 T0 pid=30060 ppid=30009 tid=-99981504  
[ ]  END  P6 T0 pid=30060 ppid=30009 tid=-99981504  
[ ] BEGIN P7 T0 pid=30061 ppid=30009 tid=-99981504  
[ ]  END  P7 T0 pid=30061 ppid=30009 tid=-99981504  
[ ] BEGIN P8 T0 pid=30062 ppid=30009 tid=-99981504  
[ ]  END  P8 T0 pid=30062 ppid=30009 tid=-99981504  
[ ]  END  P3 T0 pid=30009 ppid=30006 tid=-99981504  
[ ] BEGIN P9 T0 pid=30063 ppid=30006 tid=-99981504  
[ ] BEGIN P9 T4 pid=30063 ppid=30006 tid=-125163776  
[ ] BEGIN P9 T1 pid=30063 ppid=30006 tid=-125163776  
[ ]  END  P9 T1 pid=30063 ppid=30006 tid=-125163776  
[ ] BEGIN P9 T2 pid=30063 ppid=30006 tid=-108378368  
[ ]  END  P9 T4 pid=30063 ppid=30006 tid=-125163776  
[ ]  END  P9 T2 pid=30063 ppid=30006 tid=-108378368  
[ ] BEGIN P9 T3 pid=30063 ppid=30006 tid=-116771072  
[ ]  END  P9 T3 pid=30063 ppid=30006 tid=-116771072  
[ ]  END  P9 T0 pid=30063 ppid=30006 tid=-99981504  
[ ]  END  P1 T0 pid=30006 ppid=3467 tid=-99981504  

对于这种情况,semaphore 会很有用,

使用:

void *thread_proc(void* arg) {
   ...
   unbox arg in semaphore and id
   ...
   sem_wait(semaphore);
   // thread is running
   ...
   if(id == 13) { // special case for #13
       unsigned int count=1;
       while(count!=0) {
            sem_getvalue(semaphore,&count);
            pthread_yield();
       }
   }
   sem_post(semaphore);
   return YOUR_RESULT;
}
...
{
    sem_t semaphore;
    sem_init(&semaphore, 0, 5);

    for(int i=0;i<49;++i) {
        ...
        init a new thread and arg with i and semaphore to pass to the thread_proc
        ...

        pthread_create(thread, thread_proc, arg);
    }

请注意,不能保证 5 个线程会在任何时间点同时 运行。

一个等待作弊的方法是始终保持 4 个线程 "running" 并让一个线程 运行 随意结束,直到线程 13 结束,第 4 个阻塞的线程可以自由继续。

好吧,取决于 T13 什么时候重要 end.You 永远不知道一个线程将执行多长时间,所以最终可能不会有 5 个并发线程 运行,如果它什么时候结束并不重要,您可以计算线程数,当计数器达到 44 时,在最后 5 个线程上使用互斥锁。

int threads_running=0
pthread_t thread[49];
pthread_mutex_t lock;
int counter=0;
void *thread(some_args)
{
  if (threads_running==13) while (threads_running <5);

  if(counter==44)
  { 
    pthread_mutex_lock(&lock);
    //do smth
    if(counter==49)
     pthread_mutex_unlock(&lock); 

  }
  else
 {
 //the rest of the threads do smth
  }
}
 int main()
{
  while (counter<49)
   {
     if(threads_running<5)
     { 
       pthread_create(&thread[counter],NULL,thread,thread_arg)
       counter+=1;
       threads_running+=1;
     }
    }

}