使用C语言在ubuntu上使用sem_init

时间:2014-04-11 17:29:24

标签: c linux pthreads posix semaphore

我正在研究一些使用pthread和信号量库的代码。这是我的代码,但它不起作用,我认为它是因为sem_init函数。我是C新手,我真的不知道如何使用sem_initsem_opensem_waitsem_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;
}

2 个答案:

答案 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_initsem_destroy。命名使用sem_opensem_closesem_unlink

(2)假设您需要未命名的信号量,这对于您正在进行的相关(即分叉)进程很好,那么您必须在开始分叉之前将信号量放入共享内存中。目前,您正在将信号量放入不会在子级和父级之间共享的进程内存中,因为每个子级都将拥有自己的 copy 内存,因此实​​际上是它自己的一组信号量与任何其他过程无关。

您的程序将永远挂在sem_wait(&sem1)的父级,因为这些孩子将发出与sem1完全不同的副本的信号。