一周前,我开始理解和使用信号量和共享内存,并实际创建了这个程序,问题是我找不到任何错误,我看了几个小时,一切似乎都是正确的。。代码编译后,我可以创建构建,但当我执行它时,什么也不会发生。。。
#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;
}
孩子们应该在共享内存中写入矩阵,父亲应该读取共享内存数组并打印矩阵。
你能帮我做这个吗?谢谢你的帮助。。。
最佳答案
你的代码有几个问题。
您声明p
变量如下:
int **p;
但数组的实际类型是
int[MAXSIZE][MAXSIZE]
。尽管这两个数组都可以看作二维数组,但它们的类型完全不同,并且在内存中不共享相同的结构:int **
是指向整数指针的指针。当用作二维数组时,它描述一个二级数组。第一级(取消指针引用一次)包含一个int *
指针数组,每个指针指向一维整数数组。int[MAXSIZE][MAXSIZE]
是平面二维数组。它是指向MAXSIZE*MAXSIZE
整数数组的单指针。尽管它提供了使用两级下标的便利,但它的内存结构与一维数组相同。在C中传递指向
int[MAXSIZE*MAXSIZE]
样式数组的指针是不直观的,而且很难正确处理。我不建议这么做。您可以考虑将指针传递给type[][]
类型。尽管如此,还是有可能让它与这个声明一起工作:typedef int array2d[MAX_SIZE][MAX_SIZE];
array2d *p;
然后您必须将
matrix
和m
中的reader
参数改为writer
或array2d *m
并将其用作int **m
而不仅仅是*m
。这很难看。就像我说的,考虑改用m
类型。这个问题应该被编译器捕获。它应该会给你很多类型不匹配的警告。确保您总是使用
matrix
进行编译,目的是让您的程序在编译时没有错误和警告。在
gcc -Wall
中,设置init()
太早。您应该在分配了p
之后在函数的末尾设置它,而不是在函数的开头。正如上面的注释中所讨论的,您在
sh_mem
函数中使用了太多进程。您可能打算每次通过fork()
循环调用main()
一次,而不是两次。您不必等到编写人员完成了共享内存结构的填写,然后再继续阅读它的内容。
注意,即使在调用
fork()
之前移动for
,这还不够,因为wait(NULL)
只等待一个子进程完成,而不是所有子进程完成。一般来说,您应该在启用警告的情况下编译程序,注意这些警告,并在想知道程序可能出了什么问题之前修复它们。如果它仍然做一些意外的事情,您应该在调试器下运行它,使用断点,检查变量,并尝试查看正在发生的事情。使用这两种技术,您可能已经解决了您的问题,而无需在这里发布。