#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,原因大概 是系统版本不一样,系统自带的头文件的内容也不太一样,具体要找到头文件自己看内容