我需要为进程同步编写屏障。我做了,它一直在工作,直到我把结构屏障放在共享内存中。我的代码如下:
#include <pthread.h>
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <sys/time.h>
#include <semaphore.h>
#include <unistd.h>
#include <sys/mman.h>
#include <fcntl.h>
void nanosleep2(long t)
{
struct timespec a;
a.tv_sec = 0;
a.tv_nsec = t;
nanosleep(&a, NULL);
}
struct barrier
{
int n; // number of processes
sem_t mutex;
int count;
sem_t bar;
};
void init(struct barrier * b, int n)
{
b->n = n;
b->count = 0;
sem_init(&b->mutex, 0, 1);
sem_init(&b->bar, 0, 0);
}
void destroy(struct barrier * b)
{
sem_destroy(&b->mutex);
sem_destroy(&b->bar);
}
void wait(struct barrier * b)
{
sem_wait(&b->mutex); // It seems that some processes never get acces to mutex, but isn't it impossible?
++(b->count);
printf("Horse is there!, %d/%d\n", b->count, b->n);
if (b->count == b->n)
{
printf("the barierr is open!\n");
sem_post(&b->bar);
}
sem_post(&b->mutex);
sem_wait(&b->bar);
sem_post(&b->bar);
}
struct barrier * barr_open(const char * name)
{
int fd = shm_open(name, O_RDWR | O_CREAT, 0666);
ftruncate(fd, sizeof(struct barrier));
struct barrier * res = mmap(NULL, sizeof(struct barrier), PROT_WRITE | PROT_READ, MAP_SHARED, fd, 0);
close(fd);
return res;
}
void barr_close(struct barrier * barr, const char * name) // if name is not NULL, it also unlinks
{
munmap(barr, sizeof(struct barrier));
if (name != NULL)
shm_unlink(name);
}
const int N = 5; // number of horses
void * horse(void * _)
{
struct barrier * barr = barr_open("/barieraa");
nanosleep2((rand()%200)+10);
wait(barr);
barr_close(barr, NULL);
return NULL;
}
int main()
{
srand(time(NULL));
struct barrier * barr = barr_open("/barieraa");
init(barr, N);
sleep(1);
int i;
for (i = 0; i < N; i++)
{
pthread_t t;
pthread_create(&t, NULL, horse, NULL);
pthread_detach(t);
nanosleep2(rand()%200);
}
sleep(1);
destroy(barr);
barr_close(barr, "/barieraa");
return 0;
}
所以,在wait()中的第一个printf只有三到四匹马能够到达。可能有些东西会抓取互斥量并且不会返回,但它有可能吗?为什么屏障本身有效,共享记忆本身有效,但它们都不在一起?