简体   繁体   English

C语言中的UNIX共享内存和信号量

[英]UNIX Shared memory and Semaphores in C

I started a week ago understanding and working with semaphores and shared memory, and actually created this program; 我一周前开始了解并使用信号量和共享内存,并实际创建了该程序。 the problem is I can't find anything wrong with it. 问题是我找不到任何问题。 I've been looking at it for hours and everything seems correct. 我已经看了好几个小时,一切似乎都是正确的。 The code compiles and i can create the build but when I execute it nothing happens. 代码可以编译,我可以创建构建,但是执行时什么也没有发生。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ipc.h> 
#include <sys/shm.h>
#include <stdio.h>
#include <sys/fcntl.h>
#include <semaphore.h>

#define MAXCHILDS 4
#define MAX_SIZE 10
#define MAX_WRITES 4

typedef struct{
    int m[MAX_SIZE][MAX_SIZE];
} matrix;

/*fork variables*/
pid_t child[MAXCHILDS];
/*semphores variables */
sem_t *empty, *full, * mutex;
/*share memory id*/
int shmid;
/*shared memory array pointer */
matrix * sh_mem;
/*pointer to matrix*/
int **p;

void init(){
      /*create pointer to matrix*/
      p = &sh_mem->m;
     /*semaphores unlink and creation */    
     sem_unlink("EMPTY");
     empty=sem_open("EMPTY",O_CREAT|O_EXCL,0700,MAX_WRITES);
     sem_unlink("FULL");
     full=sem_open("FULL",O_CREAT|O_EXCL,0700,0);
     sem_unlink("MUTEX");
     mutex=sem_open("MUTEX",O_CREAT|O_EXCL,0700,1);
    /*initialize shared memory */
    shmid = shmget(IPC_PRIVATE,sizeof(matrix),IPC_CREAT|0777);
    /*map shared memory*/
    sh_mem = (matrix*)shmat(shmid,NULL,0);
    if(sh_mem== (matrix*)(-1)){
        perror("shmat");
    }
}

void writer(int ** m){
    int i,k;
    for(i = 0;i<MAX_SIZE;i++){
        for(k= 0;k<MAX_SIZE;k++){
            m[i][k] = 0;
        }
    }
}

void reader(int **m){
    int i = 0;
    int k = 0;
    for(i = 0;i<MAX_SIZE;i++){
        for(k= 0;k<MAX_SIZE;k++){
            printf(m[i][k]);
        }
        printf("\n");
    }
}

void terminate() {
  sem_close(empty);
  sem_close(full);
  sem_close(mutex);
  sem_unlink("EMPTY");
  sem_unlink("FULL");
  sem_unlink("MUTEX");
  shmctl(shmid, IPC_RMID, NULL);
}

int main(int argc, char **argv)
{
    int i;
    init();

    for(i = 0;i<MAXCHILDS;i++){
        if ((child[i] = fork()) < 0) // error occured
        {
            perror("Fork Failed");
            exit(1);
        }
        if ((child[i] = fork())==0){
            writer(sh_mem->m);
            exit(0);
        }
    }
    /*father*/  
    reader(sh_mem->m);
    wait(NULL);

    terminate();

    return 0;
}

The children are supposed to write the the matrix in shared memory, and the father is supposed to read the shared memory array and the print the matrix. 孩子应该在共享内存中写入矩阵,父亲应该读取共享内存阵列并打印矩阵。 Can you help me with this? 你能帮我吗? Thanks for the help ... 谢谢您的帮助 ...

The primary error here is that reader and writer take a different type of argument than you're passing to them, as gcc -Wall points out: 此处的主要错误是,正如gcc -Wall指出的那样, readerwriter采用的参数类型与传递给他们的参数类型不同。

test.c: In function ‘main’:
test.c:92:13: warning: passing argument 1 of ‘writer’ from incompatible pointer type [enabled by default]
test.c:49:6: note: expected ‘int **’ but argument is of type ‘int (*)[10]’
test.c:97:5: warning: passing argument 1 of ‘reader’ from incompatible pointer type [enabled by default]
test.c:58:6: note: expected ‘int **’ but argument is of type ‘int (*)[10]’

As provided, the program segfaulted in the parent and every child. 按照规定,该程序在父母和每个孩子中均被隔离。 When I changed the parameter type of reader and writer from int **m to int m[MAX_SIZE][MAX_SIZE] (along with the fixes below), the program ran successfully, as far as I can tell. 当我将readerwriter reader的参数类型从int **m更改为int m[MAX_SIZE][MAX_SIZE] (以及以下修复程序)时,据我所知,该程序成功运行。

There are a number of other errors: 还有许多其他错误:

  • You need to #include <sys/wait.h> . 您需要#include <sys/wait.h>
  • The global int **p isn't used and its initialization has the same type error as the reader and writer functions did. 没有使用全局int **p并且其初始化与读取器和写入器函数具有相同的类型错误。
  • The printf call in reader needs a format string; readerprintf调用需要格式字符串。 I used "%d " . 我使用了"%d "
  • As Jonathan Leffler pointed out, you need to call fork() only once each time through the loop in main . 正如乔纳森·莱夫勒(Jonathan Leffler)指出的那样,您每次在main的循环中只需要调用一次fork()即可。

All but the last of those were highlighted by compiler warnings. 编译器警告突出显示了除最后一个以外的所有内容。

In studying why this program was failing, I also used strace -f to identify which syscalls and processes were actually busted. 在研究该程序失败的原因时,我还使用了strace -f来确定实际破坏了哪些系统调用和进程。 The semaphore-related syscalls, for example, appear to be returning successfully--although as Jonathan pointed out, you should check their return values for errors, because failing as early as possible makes it much easier to debug problems. 例如,与信号量相关的系统调用似乎已成功返回-尽管正如乔纳森(Jonathan)指出的那样,您应该检查它们的返回值是否有错误,因为尽早失败会使调试问题变得更加容易。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM