如何解决是否可以仅使用互斥体而不是条件变量或信号量在 c 中创建自定义障碍
我完全迷失在 c 中实现自定义屏障只使用互斥而不使用 条件变量或信号量。我编写了一个使用互斥锁和条件变量组合的代码,但我只需要使用互斥锁来编写它,而不使用例如 pthread_cond_t 或 sth 类似的。
如果你知道怎么做,如果你能发送带有简要说明的源代码,我将不胜感激。
谢谢
这是我的源代码:
#include <stdio.h>
#include <stdlib.h>
#include "pthread.h"
#define NoThreadsCreated 4
// barrier data structure
typedef struct {
int maxCount; // maximum number of runners
struct sub_barrier {
pthread_mutex_t wait_lk; // mutex for waiters at barrier
pthread_cond_t wait_cv; // waiting condition for waiters at barrier
int runners; // number of running threads
} sub_barrier[NoThreadsCreated];
struct sub_barrier *sbp; // current sub_barrier
} barrier_t;
// barrier initialization function
int barrier_init(barrier_t *barrier,int count,void *arg) {
// if less then 1 thread is being created then what the hell are we doing :)
if (count < 1){
return (-1);
}
barrier->maxCount = count;
barrier->sbp = &barrier->sub_barrier[0];
for (int i = 0; i < NoThreadsCreated; ++i) {
struct sub_barrier *sbp = &(barrier->sub_barrier[i]);
sbp->runners = count;
// if initialising mutex faced error return -1
if (pthread_mutex_init(&sbp->wait_lk,arg)){
return (-1);
}
// if initialising thread's conditions faced error return -1
if (pthread_cond_init(&sbp->wait_cv,arg)){
return (-1);
}
}
// if the initialization is completed correctly return 0
return (0);
}
// barrier waiting function
int barrier_wait(barrier_t *bp) {
struct sub_barrier *sbp = bp->sbp;
// Locking threads with mutex
pthread_mutex_lock(&sbp->wait_lk);
// last thread to reach barrier
if (sbp->runners == 1) {
// check to see if the runners is 1 the number of threads are
// not 1 if it was one then why do we bother multi threading :)
if (bp->maxCount != 1) {
// reset runner count (by doing this the while loop in line 62 will not be correct any more and other threads
// will skip the while loop
sbp->runners = bp->maxCount;
// switch sub-barriers
if(bp->sbp == &bp->sbp[0]){
bp->sbp = &bp->sbp[1];
}
else{
bp->sbp = &bp->sbp[0];
}
// wake up the waiters and tell them that we faced the last thread so you can
pthread_cond_broadcast(&sbp->wait_cv);
}
} else {
// as it's not the last thread,just decrease the runners by one
sbp->runners--;
// with the help of pthread condition we are waiting for the next thread and we do not let other threads
// to pass and unlock the mutex,unless we find out that we reached the last thread
while (sbp->runners != bp->maxCount){
pthread_cond_wait(&sbp->wait_cv,&sbp->wait_lk);
}
}
pthread_mutex_unlock(&sbp->wait_lk);
return (0);
}
void *routine(barrier_t *ba) {
printf("waiting at the barrier\n");
for (int i = 0; i < NoThreadsCreated; ++i) {
barrier_wait(ba);
// do parallel computations
}
printf("We passed the barrier\n");
return NULL;
}
int main() {
int i;
barrier_t bar;
pthread_t *tid;
// initialising barrier (note that we want also have main thread
barrier_init(&bar,NoThreadsCreated+1,NULL);
tid = (pthread_t *) calloc(NoThreadsCreated,sizeof(pthread_t));
// creating threads
for (i = 0; i < NoThreadsCreated; ++i) {
if (pthread_create(&tid[i],NULL,(void *(*)(void *)) routine,&bar) != 0) {
perror("thread_creation");
exit(1);
}
}
// doing parallel computations // critical section
for (i = 0; i < NoThreadsCreated; i++) {
barrier_wait(&bar);
// do parallel computations
}
// joining threads
for (i = 0; i < NoThreadsCreated; i++) {
if(pthread_join(tid[i],NULL) != 0){
perror("thread_join");
exit(1);
}
}
return 0;
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。