UNIX 中的编程 - C 中的信号量、共享内存 [英] Programming in UNIX - Semaphores,shared memory in C

查看:52
本文介绍了UNIX 中的编程 - C 中的信号量、共享内存的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I started a week ago understanding and working with semaphores and shared memory, and actually created this program, the problem is i cant find anything wrong with it i 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(p);
            exit(0);
        }
    }
    /*father*/  
    reader(p);
    wait(NULL);

    terminate();


    return 0;
}

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

The childs 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 ...

推荐答案

您的代码有几个问题.

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

int **p;

但是你的数组的实际类型是int[MAXSIZE][MAXSIZE].虽然它们都可以被认为是二维数组,但它们的类型完全不同,在内存中也不共享相同的结构:

But the actual type of your array is int[MAXSIZE][MAXSIZE]. Although those can both be considered 2-dimensional arrays, they are not at all the same type and do not share the same structure in memory:

  • int ** 是一个指向整数指针的指针.当用作二维数组时,它描述了一个 2 级数组.第一级(取消引用指针一次)包含一个 int * 指针数组,每个指针指向一维整数数组.
  • int[MAXSIZE][MAXSIZE] 是一个平面二维数组.它是一个指向 MAXSIZE*MAXSIZE 整数数组的指针.它具有与一维数组 int[MAXSIZE*MAXSIZE] 相同的内存结构,尽管它提供了使用 2 级下标的便利.
  • int ** is a pointer to a pointer to an integer. When used as a 2-dimensional array, it describes a 2-level array. The first level (dereferencing the pointer once) contains an array of int * pointers that each point to 1-dimensional arrays of integers.
  • int[MAXSIZE][MAXSIZE] is a flat 2-dimentional array. It is a single pointer to an array of MAXSIZE*MAXSIZE integers. It has the same memory structure as the 1-dimensional array int[MAXSIZE*MAXSIZE] even though it offers the convenience of using 2 levels of subscripts.

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

Passing around pointers to type[][]-style arrays in C is non-intuitive and very difficult to get right. I don't advise doing it. You might consider passing pointers to your matrix type instead. Still, it is possible to get it to work with this declaration:

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

那么你必须将readerwriter中的m参数改为array2d *m或者int **m 并将其用作 *m 而不是 m.这变得丑陋.就像我说的,考虑使用你的 matrix 类型.

then you have to change the m parameter in reader and writer to array2d *m instead or int **m and use it as *m instead of just m. This gets ugly. Like I said, consider using your matrix type instead.

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

This problem should have been caught by the compiler. It should have been giving you lots of type mismatch warnings. Make sure you always compile with gcc -Wall and aim to have your program compile with no errors and no warnings.

init() 中,你设置了p 太早了.您应该在分配 sh_mem 之后在函数的末尾设置它,而不是在函数的开头.

In init(), you set p too early. You should set it at the end of the function after sh_mem has been assigned, not at the start of the function.

您在 main() 函数中 fork() 处理了太多进程,如上面的评论中所述.您可能打算通过 for 循环每次只调用一次 fork(),而不是两次.

You are fork()ing too many processes in your main() function, as discussed in comments above. You probably meant to call fork() only once each time through the for loop, not twice.

不要等到写入者完成了共享内存结构的填写,然后再继续阅读其内容.

You don't wait until the writers have finished filling out the shared memory structure before you go ahead and read its contents.

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

Note that even if you move your wait(NULL) before the call to reader(), that's not enough, since wait(NULL) will only wait for one child process to complete, not all of them.

通常,您应该在启用警告的情况下编译您的程序,注意警告,并在想知道您的程序可能有什么问题之前修复它们.如果它仍然出现意外,您应该在调试器下运行它,使用断点,检查变量,并尝试查看发生了什么.使用这两种技术,您可能无需在此处发帖即可解决问题.

In general, you should compile your program with warnings enabled, pay attention to the warnings, and fix them before wondering what might be wrong with your program. If it still does something unexpected, you should run it under a debugger, use breakpoints, inspect variables, and try to take a look at what's happening. Using these two techniques, you probably would have solved your problem without needing to post here.

这篇关于UNIX 中的编程 - C 中的信号量、共享内存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆