【问题标题】:Programming in UNIX - Semaphores,shared memory in CUNIX 中的编程 - 信号量,C 中的共享内存
【发布时间】:2012-10-24 19:21:16
【问题描述】:

我一周前开始了解和使用信号量和共享内存,并实际创建了这个程序,问题是我找不到任何问题我一直在看它几个小时,一切似乎都是正确的。代码编译和我可以创建构建,但是当我执行它时没有任何反应......

#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(p);
            exit(0);
        }
    }
    /*father*/  
    reader(p);
    wait(NULL);

    terminate();


    return 0;
}

孩子应该在共享内存中写入矩阵,父亲应该读取共享内存数组并打印矩阵。 你能帮我解决这个问题吗?感谢您的帮助...

【问题讨论】:

  • 第一个奇怪的是你在循环中调用了两次fork 并将结果分配给一个变量。我很确定您只想调用一次并将结果保存在变量中并使用 that 两次。
  • 副手,我可以看到你的main() 函数看起来有点像fork bomb,因为进程分叉并且父子进程再次执行 for 循环。除此之外,我认为如果您说出程序应该做什么而不是仅仅说它什么都不做,这可能会有所帮助。
  • @Celada:不,我猜只创建了 3 * MAXCHILDS。这不是真正的分叉炸弹 ;-)
  • 感谢您这么快回答,孩子们应该写入共享内存中的矩阵,而父亲应该从中读取。
  • 是的,现在我只需要一个孩子,但在我解决了这个问题后,我想为孩子们划分矩阵......如果你能帮我找出为什么这不起作用......它应该打印父亲从共享内存中读取的矩阵。

标签: c unix shared-memory semaphore


【解决方案1】:

您的代码有几个问题。

  • 您声明您的p 变量如下:

    int **p;
    

    但是你的数组的实际类型是int[MAXSIZE][MAXSIZE]。尽管它们都可以被认为是二维数组,但它们根本不是同一类型,并且在内存中不共享相同的结构:

    • int ** 是一个指向整数的指针。当用作二维数组时,它描述了一个 2 级数组。第一级(取消引用指针一次)包含一个由int * 指针组成的数组,每个指针都指向一维整数数组。
    • int[MAXSIZE][MAXSIZE] 是一个平面二维数组。它是指向MAXSIZE*MAXSIZE 整数数组的单个指针。它具有与一维数组int[MAXSIZE*MAXSIZE] 相同的内存结构,尽管它提供了使用两级下标的便利。

    在 C 中传递指向 type[][] 样式数组的指针是不直观的,并且很难正确处理。我不建议这样做。您可能会考虑将指针传递给您的 matrix 类型。尽管如此,还是可以让它与这个声明一起工作:

    typedef int array2d[MAX_SIZE][MAX_SIZE];
    array2d *p;
    

    那么您必须将readerwriter 中的m 参数改为array2d *mint **m,并将其用作*m 而不仅仅是m。这变得丑陋。就像我说的,考虑改用 matrix 类型。

    这个问题应该已经被编译器发现了。它应该给你很多类型不匹配的警告。确保您始终使用gcc -Wall 进行编译,并力求使您的程序编译时没有错误和警告。

  • init() 中,您设置p 太早了。您应该在分配sh_mem 后将其设置在函数的末尾,而不是在函数的开头。

  • 你的fork()在你的main()函数中有太多的进程,正如上面的cmets所讨论的。您可能打算每次通过for 循环只调用一次fork(),而不是两次。

  • 您不必等到编写者填写完共享内存结构后才继续阅读其内容。

    请注意,即使您在调用 reader() 之前将您的 wait(NULL) 移动,这还不够,因为 wait(NULL) 只会等待一个子进程完成,而不是所有子进程。

一般来说,您应该在启用警告的情况下编译您的程序,注意警告并修复它们,然后再想知道您的程序可能有什么问题。如果它仍然做一些意想不到的事情,你应该在调试器下运行它,使用断点,检查变量,并尝试看看发生了什么。使用这两种技术,您可能已经解决了您的问题,而无需在此处发布。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多