学习笔记:操作系统实验3共享内存块的问题

申请共享内存快后,shmat进行绑定给一个char*,死活操作不了这个char*,最后把申请的内存块大小打印出来,结果是0,但是申请内存块的函数执行是正确的,我在另一个终端通过ipc -a查看共享内存信息看到那块内存是有大小的,就是我指定申请的大小,实在找不到别的原因了...暂时记下来
#include 
#include 
#include 
#include 
#include 
#include 


#include 
#include 
#include 

/*将以上头文件 shm.h  types.h  ipc.h  stat.h 中sys改为linux后,许多奇怪的redefinition错误消失了*/
#define file_op_size 128
#define shared_segment_size 1024

void P(int semid,int index)
{
	struct sembuf sem;
	sem.sem_num=index;
	sem.sem_op=-1;
	sem.sem_flg=0;  //操作标记 0或IPC_NOWAIT等
	semop(semid,&sem,1);  //1:表示执行命令的个数
	return; 
}
void V(int semid,int index)
{
	struct sembuf sem;
	sem.sem_num=index;
	sem.sem_op=1;
	sem.sem_flg=0;  //操作标记 0或IPC_NOWAIT等
	semop(semid,&sem,1);  //1:表示执行命令的个数 
	return; 
}



int main()
{
	int status;
	char s_filename[20]="source";
	char d_filename[20]="destination";

	int segment_id[10];  //10个共享内存块
	struct shmid_ds shmbuffer;
	int segment_size;
	int ret;
	key_t num = 5630;

	pid_t p_r;	//读进程号
	pid_t p_w;      //写进程号

	char *shmaddr1;
	int i=0;
	FILE *fp1=NULL;

	char *shmaddr2;
	int j=0;	
	FILE *fp2=NULL;



	//获取文件长度
	FILE *end_p=NULL;
	long length;
	end_p=fopen(s_filename,"r");  //以只读方式打开文件,该文件必须存在。
	fseek(end_p,0L,SEEK_END);  //把文件的位置指针移到文件尾(第三个参数为从哪里开始偏移)
	length=ftell(end_p);  //获取文件长度  
	fclose(end_p);
	printf("文件长度为%ld!\n",length);
	
	
	
	//char *shared_memory;  
	//创建10个共享内存块
	for(int i=0;i<10;i++)
	{
		segment_id[i]=shmget(/*(key_t)num++*/IPC_PRIVATE,/*shared_segment_size*/1024,IPC_CREAT|0666);  //int shmget(key_t key, size_t size, int shmflg)
		if(segment_id[i]<0)
		{
			printf("shmget error\n");
			return -1;
		}
		printf("creat the shared_memory:%d\n",segment_id[i]); 	
		/*确定内存块的大小*/
		ret=shmctl(segment_id[i],IPC_STAT,&shmbuffer);
		if(ret!=0)
		{
			printf("shmctl error!\n");
			return -1;
		}
		segment_size=shmbuffer.shm_segsz;
		printf("segment size:%d\n",segment_size);  //这里输出的是0!!!
	}
	//创建信号灯
	int semid = semget(0,2,IPC_CREAT|0666);  //创建了2个信号灯
	//信号灯赋值
	union semun sem_args1;
	sem_args1.val=10;
	ret = semctl(semid,0,SETVAL,sem_args1); //0:第一个信号灯,可写的个数
	union semun sem_args2;
	sem_args2.val=0;
	ret = semctl(semid,1,SETVAL,sem_args2);     //1:第二个信号灯,可读的个数
	
    

	p_r=fork();
	if(p_r==0)
	{
		
		fp1=fopen(s_filename,"rb+");
		if(fp1==NULL)
		{
			printf("file_open_error1!\n");
			return -1;
		}
		
		// long offset=0;  
		
		//printf("sizeof shmaddr:%d\n",sizeof(shmaddr1));
		printf("读进程开始进入循环!\n");
		while(1)
		{
			P(semid,0);  //申请一个可写的信号灯(内存块)
			shmaddr1=(char *)shmat(segment_id[i],NULL,SHM_R | SHM_W); //绑定到内存共享块
			//shmaddr1=(char *)shmaddr1;
			printf("读进程已绑定到内存共享块%d!shmaddr1:%p\n",i,shmaddr1);
			/*确定内存块的大小*/
			shmctl(segment_id[i],IPC_STAT,&shmbuffer);
			segment_size=shmbuffer.shm_segsz;
			printf("segment size:%d\n",segment_size);  //这里输出的是0!!!



			printf("1\n");
			char temp[100];
			//printf("sizeof char*: %d,sizeof shmaddr:%d\n",sizeof(temp),sizeof(shmaddr));
			fread(shmaddr1,1,1,fp1);  //读数据到内存块
			printf("1\n");
			printf("读进程已读书据到内存共享块%d!\n",i);

			shmdt(shmaddr1);  //断开连接
			V(semid,1);  //添加一个可读信号灯(内存块)
			i=(i+1)%10; //0-9  9+1=0
		
			if(ftell(fp1)==length)  //到文件尾跳出
				break;
		}
		fclose(fp1);
		printf("读进程退出!\n");
		return 0;
	}

	

	p_w=fork();
	if(p_w==0)
	{
		fp2=fopen(d_filename,"w+"); //
		if(fp2==NULL)
		{
			printf("file_open_error2!\n");
			return -1;
		}

		printf("sizeof shmaddr:%d\n",sizeof(shmaddr2));
		printf("写进程开始进入循环!\n");
		while(1)
		{
			P(semid,1);  //申请一个可读信号灯(内存块)
			shmaddr2=(char *)shmat(segment_id[j],NULL,SHM_R | SHM_W); //绑定到内存共享块
			printf("写进程已绑定到内存共享块%d!\n",i);

			strcpy(shmaddr2,"Hi,I am child pocess!\n");
			printf("%s\n", shmaddr2);

			fwrite(shmaddr2,1,file_op_size,fp2);
			printf("写进程已从内存共享块%d写入到文件!\n",i);
			shmdt(shmaddr2);  //断开连接
			V(semid,0);  //添加一个可写信号灯(内存块)
			j=(j+1)%10; //0-9  9+1=0
			
			if(ftell(fp2)==length)  //到文件尾跳出
				break;
		}
		fclose(fp2);
		printf("写进程退出!\n");
		return 0;
	}

	waitpid(p_w,&status,0);
	waitpid(p_r,&status,0);

	//destroy10个共享内存块
	for(int i=0;i<10;i++)
		{
			shmctl(segment_id[i],IPC_RMID,0);
			printf("creat the shared_memory:%d\n",i); 	
		}
	// 删除信号灯 
	ret =semctl(semid,1,IPC_RMID);
	printf("主进程退出!\n");
	return 0;
}

终于找到问题了,头文件改为:

#include 
#include 
#include 
#include 
#include 
#include 




#include 
#include     //!!!can't use linux!!!
#include 

就好了,真是GG,原因大概 是系统版本不一样,系统自带的头文件的内容也不太一样,具体要找到头文件自己看内容

你可能感兴趣的:(学习笔记:操作系统实验3共享内存块的问题)