學習筆記:操作系統實驗3共享內存塊的問題

申請共享內存快後,shmat進行綁定給一個char*,死活操作不了這個char*,最後把申請的內存塊大小打印出來,結果是0,但是申請內存塊的函數執行是正確的,我在另一個終端通過ipc -a查看共享內存信息看到那塊內存是有大小的,就是我指定申請的大小,實在找不到別的原因了...暫時記下來
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <string.h>
#include <linux/ipc.h>
#include <linux/shm.h>


#include <sys/stat.h>
#include <linux/sem.h>
#include <sys/wait.h>

/*將以上頭文件 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 <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/shm.h>




#include <sys/stat.h>
#include <sys/sem.h>    //!!!can't use linux!!!
#include <sys/wait.h>

就好了,真是GG,原因大概 是系統版本不一樣,系統自帶的頭文件的內容也不太一樣,具體要找到頭文件自己看內容

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章