我正在研究一些使用pthread和信号量库的代码。这是我的代码,但它不起作用,我认为它是因为sem_init
函数。我是C新手,我真的不知道如何使用sem_init
,sem_open
,sem_wait
和sem_post
。有人可以给我一些建议吗?
#include <sys/mman.h>
#include <math.h>
#include <wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <semaphore.h>
#include <sys/sem.h>
#include <sys/types.h>
#include <unistd.h>
#include<fcntl.h>
sem_t sem1,sem2;
float Calculate(int a,int b)
{
float d = ((a *a) + (b*b))/2;
return d;
}
int main()
{
int q;
int i,j,x;
float *Maddress, m, sum;
Maddress=mmap(NULL,sizeof(float),PROT_READ|PROT_WRITE,MAP_SHARED,-1,0);
sem_init(&sem2,0,1);
sem_init(&sem1,0,0);
sem_open("sem2",O_CREAT);
sem_open("sem1",O_CREAT);
if((q = sem_init(&sem1,1,0))!=0)
printf("error in create\n");
for(i=1;i<=10;i++)
{
j=fork();
if(j==0)
{
printf("The child %d is executing\n",i);
m=Calculate(i-1,i);
printf("child %d calculated value: %f\n",i,m);
sem_wait(&sem2);
Maddress=&m;
sem_post(&sem1);
exit(EXIT_SUCCESS);
}
}
for(j=1;j<=10;j++)
{
wait(&x);
if(WIFEXITED(x))
{
sem_wait(&sem1);
sum=sum+ (*Maddress);
sem_post(&sem2);
}
}
printf("The final result is: %f \n",sum);
sem_close(&sem1);
sem_close(&sem2);
return 0;
}
答案 0 :(得分:1)
你应该像这样定义你的信号量:
sem_t sem1, sem2;
就sem_init()
而言,根据man 3 sem_init
,原型是:
int sem_init(sem_t *sem, int pshared, unsigned int value);
所以你必须像这样传递信号量:
sem_init(&sem1, 0, 0);
或者您需要的初始值。
同样适用于sem_wait()
和sem_post()
。
答案 1 :(得分:0)
(1)有两种POSIX信号量 - 命名和未命名 - 你要混合它们。未命名的信号量使用sem_init
和sem_destroy
。命名使用sem_open
,sem_close
和sem_unlink
。
(2)假设您需要未命名的信号量,这对于您正在进行的相关(即分叉)进程很好,那么您必须在开始分叉之前将信号量放入共享内存中。目前,您正在将信号量放入不会在子级和父级之间共享的进程内存中,因为每个子级都将拥有自己的 copy 内存,因此实际上是它自己的一组信号量与任何其他过程无关。
您的程序将永远挂在sem_wait(&sem1)
的父级,因为这些孩子将发出与sem1完全不同的副本的信号。