【问题标题】:sem_init on ubuntu using C-Languagesem_init 在 ubuntu 上使用 C 语言
【发布时间】:2014-04-11 17:29:24
【问题描述】:

我正在编写一些使用 pthread 和 semaphore 库的代码。这是我的代码,但它不起作用,我认为这是因为 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;
}

【问题讨论】:

    标签: c linux pthreads posix semaphore


    【解决方案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()

    【讨论】:

    • 我按照你说的修改了代码并编辑了我的问题。更改代码后它几乎可以工作,但现在第二个“for”没有运行,我真的不知道为什么!!
    【解决方案2】:

    (1) 有两种 POSIX 信号量——命名的和未命名的——你正在混合使用这两种信号量。未命名的信号量使用sem_initsem_destroy。命名使用sem_opensem_closesem_unlink

    (2) 假设您想要未命名的信号量,这些信号量适用于您正在做的相关(即分叉)进程,那么您必须在开始分叉之前将信号量放入共享内存中。目前,您正在将信号量放入不会在子进程和父进程之间共享的进程内存中,因为每个子进程都将获得它自己的 copy 内存,因此,实际上,它自己的一组信号量不会与任何其他进程相关。

    您的程序将在sem_wait(&amp;sem1) 的父级中永远挂起,因为子级将发出一个完全不同的副本 sem1 信号。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-01-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-27
      • 1970-01-01
      相关资源
      最近更新 更多