当前位置: 技术问答>linux和unix
帮忙看看这个Linux共享内存程序什么地方有问题?
来源: 互联网 发布时间:2017-01-02
本文导语: 问题是这个样子的,我利用共享内存在两个进程之间传递数据,一个是消费者,另一个是 生产者。他们的代码很类似。 消费者代码: #include #include #include #include #include #include #include #include #include #include...
问题是这个样子的,我利用共享内存在两个进程之间传递数据,一个是消费者,另一个是
生产者。他们的代码很类似。
消费者代码:
生产者代码:
在执行过程中,让消费者先跑起来,那么它会在信号量那个阻塞自己,这个正常。
之后让生产者跑起来,此时又出现了经典的段错误。
我首先让消费者跑起来后:
ipcs -m 发现
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x00000000 720914 luoxiongwe 600 393216 2 dest
0x00000000 753683 luoxiongwe 600 393216 2 dest
0x00000000 786452 luoxiongwe 600 12288 2 dest
0x00000000 819221 luoxiongwe 600 393216 2 dest
0x00000000 1146902 luoxiongwe 600 393216 2 dest
0x00000000 1310743 luoxiongwe 600 358620 2 dest
0x00012356 1343512 luoxiongwe 666 4 1
《unix高级环境编程》上面不是说由key去标识一个共享内存段吗?系统中怎么会后这么多的0x00000000?
我的进程的共享内存段的信息在最后一行。
我在中间输出了一些结果:
shmid=1343512
共享内存段在 B785B000
---------------------------------------
之后运行生产者进程,错误出现了。
shmid=1343512
共享内存段在 B7760000
段错误
他们的shmid竟然是相同的,而且共享段的起始地址居然不一样?
这是产生段错的原因吗?
《unix高级环境编程》说道:系统中的key值唯一标识一个共享内存段,shmid在不同的进程之间可以不同。
但是系统中的输出信息却表示key可以相同,但是shmid却不一样。
我在两个进程中的shmid是一样的。
请问这到底是怎么回事?
我的分数不多,而且问题有点长,请高手帮忙解答一下。谢谢了!
我现在在写一个日志系统,想利用共享内存实现进程中间的通信,
没有想到,预先写的一个小测试程序都有问题。
生产者。他们的代码很类似。
消费者代码:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using std::string;
union semun
{
int val; /* Value for SETVAL */
struct semid_ds *buf; /* Buffer for IPC_STAT, IPC_SET */
unsigned short *array; /* Array for GETALL, SETALL */
struct seminfo *__buf; /* Buffer for IPC_INFO(Linux-specific) */
};
string buf;//存储记录
//与共享内存有关的变量
int shmid=-1;// 共享内存的id
void * shm_re=(void *)0;
string * shm_records;// 保存共享内存的起始位置
int full=-1;
int empty=-1;
//函数接口说明
void daemon_start_task();//初始化函数
//封装的信号量处理接口
int set_semvalue(int sem_v,int semid);
void del_semvalue(int semid);
int sem_post(int semid);//加操作
int sem_wait(int semid);//减操作
int main(int argc,char * arg[])
{
daemon_start_task();
//设置两个信号量的初始值
set_semvalue(0,full);
set_semvalue(1,empty);
for(;;)
{
sem_wait(full);
printf("%sn",(*shm_records).c_str());
sem_post(empty);
sleep(2);
}
return 0;
}
void daemon_start_task()
{
shmid=shmget((key_t)0x12356,sizeof(string),0666|IPC_CREAT);
printf("shmid=%dn",shmid);
shm_re=shmat(shmid,NULL,0);
shm_records=(string *)shm_re;//此时可以使用共享内存
printf("共享内存段在 %Xn",(int)shm_re);
full=semget((key_t)0x8978,1,0666|IPC_CREAT);//只需要由消费者初始化一次即可
empty=semget((key_t)0x74566,1,0666|IPC_CREAT);
}
//1成功,0失败
/*函数功能:将semid的信号量的
初始值设置为sem_v
*/
int set_semvalue(int sem_v,int semid)
{
union semun sem_union;
sem_union.val=sem_v;
if(semctl(semid,0,SETVAL,sem_union)==-1)
return 0;
return 1;
}
//该函数将semid的信号量删除
void del_semvalue(int semid)
{
union semun sem_un;
semctl(semid,0,IPC_RMID,sem_un);
}
//该函数将semid信号量值加1
//1成功,0失败
int sem_post(int semid)
{
struct sembuf sem_b;
sem_b.sem_num=0;
sem_b.sem_op=1;
sem_b.sem_flg=SEM_UNDO;
if(semop(semid,&sem_b,1)==-1)
return 0;
return 1;
}
//该函数将semid信号量值减1
//1成功,0失败
int sem_wait(int semid)
{
struct sembuf sem_b;
sem_b.sem_num=0;
sem_b.sem_op=-1;
sem_b.sem_flg=SEM_UNDO;
if(semop(semid,&sem_b,1)==-1)
return 0;
return 1;
}
生产者代码:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using std::string;
union semun
{
int val; /* Value for SETVAL */
struct semid_ds *buf; /* Buffer for IPC_STAT, IPC_SET */
unsigned short *array; /* Array for GETALL, SETALL */
struct seminfo *__buf; /* Buffer for IPC_INFO(Linux-specific) */
};
string buf;//存储记录
//与共享内存有关的变量
int shmid=-1;// 共享内存的id
void * shm_re=(void *)0;
string * shm_records;// 保存共享内存的起始位置
int full=-1;
int empty=-1;
//函数接口说明
void daemon_start_task();//初始化函数
//封装的信号量处理接口
int set_semvalue(int sem_v,int semid);
void del_semvalue(int semid);
int sem_post(int semid);//加操作
int sem_wait(int semid);//减操作
int main(int argc,char * arg[])
{
daemon_start_task();
for(int i=0;i!=5;++i)
{
sem_wait(empty);
*shm_records="come from production";
sem_post(full);
sleep(2);
}
return 0;
}
void daemon_start_task()
{
shmid=shmget((key_t)0x12356,sizeof(string),0666|IPC_CREAT);
printf("shmid=%dn",shmid);
shm_re=shmat(shmid,NULL,0);
shm_records=(string *)shm_re;//此时可以使用共享内存
printf("共享内存段在 %Xn",(int)shm_re);
full=semget((key_t)0x8978,1,0666|IPC_CREAT);//只需要由消费者初始化一次即可
empty=semget((key_t)0x74566,1,0666|IPC_CREAT);
}
//1成功,0失败
/*函数功能:将semid的信号量的
初始值设置为sem_v
*/
int set_semvalue(int sem_v,int semid)
{
union semun sem_union;
sem_union.val=sem_v;
if(semctl(semid,0,SETVAL,sem_union)==-1)
return 0;
return 1;
}
//该函数将semid的信号量删除
void del_semvalue(int semid)
{
union semun sem_un;
semctl(semid,0,IPC_RMID,sem_un);
}
//该函数将semid信号量值加1
//1成功,0失败
int sem_post(int semid)
{
struct sembuf sem_b;
sem_b.sem_num=0;
sem_b.sem_op=1;
sem_b.sem_flg=SEM_UNDO;
if(semop(semid,&sem_b,1)==-1)
return 0;
return 1;
}
//该函数将semid信号量值减1
//1成功,0失败
int sem_wait(int semid)
{
struct sembuf sem_b;
sem_b.sem_num=0;
sem_b.sem_op=-1;
sem_b.sem_flg=SEM_UNDO;
if(semop(semid,&sem_b,1)==-1)
return 0;
return 1;
}
在执行过程中,让消费者先跑起来,那么它会在信号量那个阻塞自己,这个正常。
之后让生产者跑起来,此时又出现了经典的段错误。
我首先让消费者跑起来后:
ipcs -m 发现
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x00000000 720914 luoxiongwe 600 393216 2 dest
0x00000000 753683 luoxiongwe 600 393216 2 dest
0x00000000 786452 luoxiongwe 600 12288 2 dest
0x00000000 819221 luoxiongwe 600 393216 2 dest
0x00000000 1146902 luoxiongwe 600 393216 2 dest
0x00000000 1310743 luoxiongwe 600 358620 2 dest
0x00012356 1343512 luoxiongwe 666 4 1
《unix高级环境编程》上面不是说由key去标识一个共享内存段吗?系统中怎么会后这么多的0x00000000?
我的进程的共享内存段的信息在最后一行。
我在中间输出了一些结果:
shmid=1343512
共享内存段在 B785B000
---------------------------------------
之后运行生产者进程,错误出现了。
shmid=1343512
共享内存段在 B7760000
段错误
他们的shmid竟然是相同的,而且共享段的起始地址居然不一样?
这是产生段错的原因吗?
《unix高级环境编程》说道:系统中的key值唯一标识一个共享内存段,shmid在不同的进程之间可以不同。
但是系统中的输出信息却表示key可以相同,但是shmid却不一样。
我在两个进程中的shmid是一样的。
请问这到底是怎么回事?
我的分数不多,而且问题有点长,请高手帮忙解答一下。谢谢了!
我现在在写一个日志系统,想利用共享内存实现进程中间的通信,
没有想到,预先写的一个小测试程序都有问题。
|
0 的那些是IPC_PRIVATE 方式创建的吧?