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

标签 c linux shared-memory semaphore

我需要编写一个程序来创建 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__

ma​​in.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;
}

slaveproc.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;
}

最佳答案

问题(或至少是“一个问题”)是 mutex 不在共享内存中:它分配在堆栈上。当您fork() 时,新进程将拥有与旧进程完全独立的副本,因此在一个进程上调用sem_wait(&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 - 在 Linux 下使用信号量和共享内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32980493/

相关文章:

c - 将文本文件中的整数存储到整数数组中

c - 将指向结构数组的指针设置为等于结构数组

c - 我的c代码有什么问题?

php - 如何在后台运行 php 脚本而不导致浏览器显示加载动画?

c - 为什么终端 session 结束时所有进程都被杀死?

c - 使用 openGL 从 C 中的文件或指针打印值

linux - 无法安装 Vision Workbench

C 子进程无法访问共享内存

C 中具有共享内存和信号量的客户端服务器程序

linux - 如何在 Linux 中选择共享内存接口(interface)?