当前位置: 首页 > 知识库问答 >
问题:

为什么未命名信号量在共享内存中使用时不会改变?

赵钊
2023-03-14

我必须使2个进程(服务器/客户机),可以访问相同的共享内存。我通过服务器和客户端之间的UNIX套接字发送共享内存的密钥。然后,我创建共享内存段,并使用未命名的信号量来同步服务器/客户机。正如我所想的那样,我做的一切都是正确的,但是当我运行客户机进程时,我可以看到信号量甚至没有初始化!

Server.c示例

#include <stdlib.h>
#include <stdio.h> 
#include <semaphore.h>
#include <unistd.h>
#include <errno.h>

sem_t *semaphore;

int main(int argc, char **argv){

//...making the connections here
// M is the number of semaphores i will use
    key_t key3;
    int shmid3;
    if ((shmid3 = shmget(key3, M*sizeof(sem_t), 0644 | IPC_CREAT)) == -1) {
      perror("shmget3");
      exit(1);
    }
    key3 = htonl(key3);
        if (send(s2, (const char*)&key3, 4, 0) == -1) {
            perror("send");
            exit(1);
    }
    int i;
    semaphore=(sem_t *)shmat(shmid3, (void *) 0, 0);
    if (semaphore == (sem_t *)(-1)) perror("shmat");
    for(i=0;i<M;i++) if(sem_init(&semaphore[i], 1, 1)!=0) perror("sem_init");
//..do some stuff...
    sleep(3);

    for(i=0;i<M;i++) sem_destroy( &semaphore[i] );
    if (shmdt(semaphore) == -1) {
      perror("shmdt");
      exit(1);
    }
    shmctl(shmid3, IPC_RMID, NULL);
//close connection...
}
#include <stdlib.h>
#include <stdio.h> 
#include <semaphore.h>
#include <unistd.h>
#include <errno.h>

sem_t *semaphore;

int main(int argc, char **argv){

//...making the connections here
// M is the number of semaphores i will use
    key_t key3;
    n = recv(s, &key3, 4, 0);
        if (n < 0) {
           perror("recv");
        }
        key3 = ntohl(key3); 
    int shmid3;
    if ((shmid3 = shmget(key3, M*sizeof(sem_t), 0644 )) == -1) {
      perror("shmget3");
      exit(1);
    }

    semaphore=(sem_t *)shmat(shmid3, (void *) 0, 0);
    if (semaphore == (sem_t *)(-1)) perror("shmat");

    int value;
    sleep(1); 
    sem_getvalue(&semaphore[0], &value); 
    printf("\n[%d]\n",value); //always prints 0

    //...do stuff...
    if (shmdt(semaphore) == -1) {
  perror("shmdt");
  exit(1);
}
//close connection...
}

UNIX连接没有任何问题,因为我共享和其他内存段,它们工作得很好。我还尝试更改sem_initpshared参数,但客户端中仍然没有任何变化。我实际上想在Clinet的线程(M)中使用信号量,但我看到它们甚至在主进程中都没有初始化。

共有1个答案

颜思淼
2023-03-14

(根据注释中的疑难解答改编...)

未初始化的key_t key3恰好被初始化为值IPC_PRIVATE,这意味着为shmget()的每个调用者创建了一个新的共享内存段。应该显式初始化密钥(在本例中是通过ftok())。

 类似资料:
  • 我需要编写一个程序,它正在创建N个数量的子进程,每一个进程都将一个添加到共享内存变量中。我的想法是使用信号量和共享内存,但进程之间并没有相互等待,共享内存变量也没有像我希望的那样工作。 MyDefs.H Main.C 奴隶Proc.c

  • 我想创建一个共享内存和信号量的C程序。应该有两个子进程。两个孩子都有一个不同的int数。然后有一个目标号码,应该写在共享内存中。现在两个孩子都应该从进球数中减去他们的数字,直到进球数低于或等于0。我不希望出现比赛条件。这就是为什么我尝试使用信号量。但对我没用。下面是我的代码:

  • 我在编写一些简单的代码来自学信号量和POSIX共享内存时遇到了问题。 其思想是一个程序,即服务器,打开共享内存并向其中写入一个结构(包含信号量和数组)。然后它等待输入,输入之后信号量递增。 同时,客户端打开共享内存,等待信号量,在服务器增加信号量之后,读取结构。 服务器似乎工作正常,但是我在客户端的函数处立即遇到了一个segfault(甚至在服务器增加它之前)。我想不出哪里出了问题。 服务器代码:

  • 我尝试编写一个共享内存和信号量程序,该程序一直运行到按下Ctrl+C,即接收到: 当按下Ctrl+C时,被设置为,它会跳出循环并退出。在没有共享内存和信号量的情况下,这可以很好地工作,但是在这里,我从来没有在上获得字符串,只捕获并且它继续运行。 为什么?

  • null 有3个信号量:互斥-初始化为1满-初始化为0空-初始化为n(而n是管道中的“字节”数) 消费者代码: 生产者代码: 如有任何帮助,不胜感激,谢谢!