程序原理:
此程序可以用来模拟异构多核的处理器之间的相互通信以及Linux系统下多进程之间的数据直接共享,原理如下图所示:
1.Server端(生产者端)
#include <sys/msg.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <sys/ipc.h>
#include <stdio.h>
#include <stdlib.h>
#include "ringbuffer.h"
union semun
{
int val; //信号量初始值
struct semid_ds *buf;
unsigned short int *array;
struct seminfo *__buf;
};
int main()
{
struct ringbuffer *rb;
int shm_key = ftok(".",0x5a);
//第二个参数(创建共享内存的大小)
int shm_id = shmget(shm_key, 1024*1024 + sizeof(struct ringbuffer), IPC_CREAT|IPC_EXCL|0755);
if(shm_id == -1)
{
perror("shmget.");
exit(1);
}
printf("%s line %d, shm_id=%d ,shm_key=0x%x.\n", __func__, __LINE__, shm_id,shm_key);
char *address = (char*)shmat(shm_id, NULL, 0);
if((void*)address == (void*)-1)
{
perror("shmat.");
shmctl(shm_id, IPC_RMID, 0);
exit(1);
}
rb = (struct ringbuffer*)address;
ringbuffer_init(rb, (void*)sizeof(struct ringbuffer), 1024);
key_t sem_key = ftok(".", 0x6b);
int sem_id = semget(sem_key, 2, IPC_CREAT|IPC_EXCL|0755);
union semun info;
info.val = 0;
semctl(sem_id,0, SETALL, info);
struct sembuf p ={0, -1, 0}, v = {1, 1,0};
unsigned char w = 0;
while(1)
{
if(ringbuffer_put(rb, &w, 1) == 1)
{
w ++;
printf("server: %s line %d.r %d, w %d.\n", __func__, __LINE__, rb->read_index, rb->write_index);
}
semop(sem_id, &v, 1);
semop(sem_id, &p, 1);
}
shmdt(address);
shmctl(shm_id, IPC_RMID, 0);
shmctl(sem_id, 0, IPC_RMID);
return 0;
}
2.Client端(消费者端)
#include <sys/msg.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <sys/ipc.h>
#include <stdio.h>
#include <stdlib.h>
#include "ringbuffer.h"
union semun
{
int val; //信号量初始值
struct semid_ds *buf;
unsigned short int *array;
struct seminfo *__buf;
};
int main()
{
struct ringbuffer *rb;
int shm_key = ftok(".",0x5a);
int shm_id = shmget(shm_key, 0, 0);
if(shm_id == -1)
{
perror("shmget.");
exit(1);
}
printf("%s line %d, shm_id=%d ,shm_key=0x%x.\n", __func__, __LINE__, shm_id,shm_key);
char *address = (char*)shmat(shm_id, NULL, 0);//NULL连接的地址由系统自动分配
if((void*)address == (void*)-1)
{
perror("shmat.");
exit(1);
}
rb = (struct ringbuffer *)address;
printf("address = %p\n", address);
rb = (struct ringbuffer*)address;
//ringbuffer_init(rb, address + sizeof(struct ringbuffer), 1024);
key_t sem_key = ftok(".",0x6b);
int sem_id = semget(sem_key, 0, 0);
struct sembuf p = {