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

在Linux下使用信号量和共享内存

叶鸿
2023-03-14

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

MyDefs.H

#ifndef __MYDEFS__H__
#define __MYDEFS__H__
// Includes
#include <stdio.h>
#include <unistd.h>
#include <semaphore.h>
#include <stdlib.h>
#include <signal.h>
#include <errno.h>
#include <memory.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/types.h>
#include <sys/shm.h>
#endif // __MYDEFS__H__

Main.C

#include "mydefs.h"
#define PROC_COUNT 3
#define INITAL_MARKER_VALUE 0
#define PID_LEN 32

char mypid[PID_LEN];

int main()
{
    int i, shm_id;
    sem_t mutex;
    if(sem_init(&mutex,1,1) < 0)
    {
        perror("semaphore initilization");
        exit(0);
    }
    shm_id = shmget(IPC_PRIVATE, 4*sizeof(int), IPC_CREAT | 0666);
    if (shm_id < 0) {
         printf("shmget error\n");
    }
    int *shmpointer = shmat(shm_id,0,0);
    memset(mypid, 0, sizeof(mypid));
    sprintf(mypid, "%06d", getpid());

    for(i = 0; i < PROC_COUNT; i++)
    {
        if (fork() == 0)
        {
            while(sem_wait(&mutex)!=0);
            execl("slaveproc", "slaveproc", mypid, (char *)0);
            shmpointer += 1;
            sem_post(&mutex);
            perror("\n Can't exec slave program. Cause ");
            exit(1);
        }
    }
    sleep(1);
    printf("%d\n", *shmpointer);
    return 0;
}

奴隶Proc.c

#include "mydefs.h"

int marker; // Marker value

int main(int argc, char *argv[])
{
    master_pid = atoi(argv[1]);
    printf("\n --------------------------------------");
    printf("\n I'm the slave proc!");
    printf("\n My pid: %d", getpid());
    printf("\n My master's pid: %d", master_pid);
    printf("\n --------------------------------------");
    for(;;) pause();
        return 0;
}

共有1个答案

陆飞鸿
2023-03-14

问题(或者至少是“问题”)在于mutex不在共享内存中:它分配在堆栈上。当您fork()时,新进程将有一个与旧进程完全不同的副本,因此对一个进程调用sem_wait(&mutex)不会影响另一个进程的mutex

您应该将mutex放在共享内存中:

int main()
{
    int i, shm_id;
    shm_id = shmget(IPC_PRIVATE, sizeof(sem_t) + 4*sizeof(int), IPC_CREAT | 0666);
    if (shm_id < 0) {
         printf("shmget error\n");
    }
    int *shmpointer = shmat(shm_id,0,0);
    sem_t *mutex = shmpointer;
    shmpointer = (void*)shmpointer + sizeof(sem_t);
    if(sem_init(mutex,1,1) < 0)
    {
        perror("semaphore initilization");
        exit(0);
    }        
    memset(mypid, 0, sizeof(mypid));
    sprintf(mypid, "%06d", getpid());

    for(i = 0; i < PROC_COUNT; i++)
    {
        if (fork() == 0)
        {
            while(sem_wait(mutex)!=0);
            execl("slaveproc", "slaveproc", mypid, (char *)0);
            shmpointer += 1;
            sem_post(mutex);
            perror("\n Can't exec slave program. Cause ");
            exit(1);
        }
    }
    sleep(1);
    printf("%d\n", *shmpointer);
    return 0;
}

您也从未在shmpointer中写入内存(也许您指的是(*shmpointer)+=1?),但我会让您自己理解。

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

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

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

  • 我在Linux上使用C。我需要构建使用共享内存和信号量进行通信的两个程序。 其中一个程序必须充当服务器(一次只能充当一个),另一个程序必须充当客户机(一次任意数量)。通信应遵循以下模式: 我知道如何在两个进程之间使用共享内存和信号量,但我不知道如何在数量不明的进程之间进行通信时使用它们。我考虑为每个客户机使用共享内存块,但我必须交换密钥并通知服务器新的客户机。所以这并不能解决问题。

  • 程序应该创建200000个整数,并将2000个写入共享内存。分叉进程应该从共享内存中读取2000,父进程应该将下一个2000写入共享内存。 请帮帮我们谢谢你们 编辑:非常感谢您的回答。我不能标出正确的答案,因为我不知道什么是正确的。但我不想再尝试了。15个小时就够了