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,¶ms1[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 会很有用,
使用:
sem_init
初始化为想要的值
sem_post
增加值
sem_wait
递减和阻塞
而信号量值为零
sem_getvalue
获取信号量的值
示例:
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;
}
}
}
我应该在某个进程中创建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,¶ms1[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 会很有用,
使用:
sem_init
初始化为想要的值sem_post
增加值sem_wait
递减和阻塞 而信号量值为零sem_getvalue
获取信号量的值 示例:
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;
}
}
}