Linux共享内存示例,使用信号量同步
2015-11-26 16:42
681 查看
1、shm_test1.c
2、shm_test2.c
以上两个程序实现的功能:shm_test1接收用户输入命令,如果是send则将向共享内存区域写入一个报文,并发送socket消息通知进程shm_test2从共享内存中读出报文并打印出来。
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <stddef.h> #include <errno.h> #include <sys/un.h> #include <sys/types.h> #include <sys/sem.h> #include <sys/shm.h> #include <sys/stat.h> #include <sys/socket.h> #define SEM_KEY 100 #define SHM_KEY 101 #define TOTAL_SEM 10 #define UNIX_DOMAIN "/tmp/unix_sock" typedef struct shared_use { int pktlen; unsigned char pkt[1528]; } shared_use_t; static unsigned char ucast_pkt[] = { 0x00, 0xd0, 0xf8, 0x00, 0x99, 0x22, 0x00, 0x00, 0x00, 0x01, 0x01, 0x07, 0x08, 0x06, 0x00, 0x01, 0x08, 0x00, 0x06, 0x04, 0x00, 0x01, 0xbc, 0x30, 0x00, 0x00, 0x00, 0x01, 0x01, 0x07, 0xc0, 0xa8, 0xcc, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xa8, 0xcc, 0x64 4000 , 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14}; static int sem_id = 0; static int com_fd = 0; static void *shm = NULL; /* 获取信号量资源 */ static int semaphore_v(void) { struct sembuf sem_b; sem_b.sem_num = 0; sem_b.sem_op = 1; sem_b.sem_flg = SEM_UNDO; if (semop(sem_id, &sem_b, 1) == -1) { return -1; } return 0; } /* 释放信号量资源 */ static int semaphore_p(void) { struct sembuf sem_b; sem_b.sem_num = 0; sem_b.sem_op = -1; sem_b.sem_flg = SEM_UNDO; if (semop(sem_id, &sem_b, 1) == -1) { return -1; } return 0; } /* 初始化信号量 */ static int semaphore_init(void) { union semun sem_union; sem_id = semget((key_t)SEM_KEY, 1, 0666 | IPC_CREAT); if (sem_id == -1) { return -1; } sem_union.val = 1; if (semctl(sem_id, 0, SETVAL, sem_union) == -1) { return -1; } return 0; } /* 初始化共享内存 */ static int sharemmy_init(void) { int shmid; /* 创建共享内存区域块 */ shmid = shmget((key_t)SHM_KEY, sizeof(shared_use_t), 0666 | IPC_CREAT); if (shmid == -1) { return shmid; } /* 将本进程的虚拟内存映射到共享内存 */ shm = shmat(shmid, (void *)0, 0); if (shm == (void *)-1) { return -1; } return shmid; } static int sharemmy_destroy(int shmid, void *shm) { int rv; /* 删除本进程与共享内存的映射 */ rv = shmdt(shm); if (rv == -1) { return rv; } /* 删除创建的共享内存块 */ rv = shmctl(shmid, IPC_RMID, 0); if (rv == -1) { return rv; } return 0; } static int domain_server(void) { int rv; int listen_fd; socklen_t len; struct sockaddr_un srv_un; struct sockaddr_un clt_un; listen_fd = socket(PF_UNIX, SOCK_STREAM, 0); if (listen_fd < 0) { perror("socket: "); return -1; } memset(&srv_un, 0, sizeof(srv_un)); srv_un.sun_family = AF_UNIX; strncpy(srv_un.sun_path, UNIX_DOMAIN, sizeof(srv_un.sun_path) - 1); unlink(UNIX_DOMAIN); rv = bind(listen_fd, (struct sockaddr *)&srv_un, sizeof(srv_un)); if (rv < 0) { perror("bind: "); close(listen_fd); unlink(UNIX_DOMAIN); return -1; } rv = listen(listen_fd, 1); if (rv < 0) { perror("listen: "); close(listen_fd); unlink(UNIX_DOMAIN); return -1; } len = sizeof(clt_un); while (1) { com_fd = accept(listen_fd, (struct sockaddr *)&clt_un, &len); if (errno == EINTR && com_fd == -1) { continue; } break; } return 0; } static void print_cmd_help(void) { printf("CAMMAND NOT SUPPORT!.\n"); printf("********** Help Info **********\n"); printf(" 1. Send -------- send a packet to commad.\n"); printf(" 2. Quit -------- quit the program.\n"); printf("********** End **********\n"); } static int shmwrite(void *shm) { int rv; shared_use_t *shared; rv = semaphore_p(); if (rv < 0) { return -1; } shared = (shared_use_t *)shm; shared->pktlen = sizeof(ucast_pkt); memcpy(shared->pkt, ucast_pkt, sizeof(ucast_pkt)); rv = semaphore_v(); if (rv < 0) { return -1; } return 0; } int main() { int rv; int shmid; char cmd[10]; rv = semaphore_init(); if (rv < 0) { printf("Init a semaphore fail.\n"); return 0; } shmid = sharemmy_init(); if (shmid == -1) { printf("Init a share memory fail.\n"); return 0; } rv = domain_server(); if (rv < 0) { printf("Create domain server socket fail.\n"); return 0; } printf("Server init success!\n"); printf("\n"); while (1) { memset(cmd, 0, sizeof(cmd)); printf("Enter a command:"); scanf("%s", cmd); if (cmd[9] != 0) { printf("Error : Command is too long, at most 9 char allowed!!!\n"); continue; } else if (strstr(cmd, "send") != NULL || strstr(cmd, "Send") != NULL) { rv = shmwrite(shm); if (rv < 0) { printf("Write packet to share memory fail.\n"); break; } rv = send(com_fd, cmd, sizeof(cmd), 0); if (rv < 0) { printf("Send command send fail.\n"); continue; } } else if (strstr(cmd, "quit") != NULL || strstr(cmd, "Quit") != NULL) { printf("**********Stop Send Packet To Client.***********\n"); rv = send(com_fd, cmd, sizeof(cmd), 0); if (rv < 0) { printf("Quit commadn send fail.\n"); } break; } else { print_cmd_help(); } printf("\n"); } usleep(1000); rv = sharemmy_destroy(shmid, shm); if (rv < 0) { printf("Destroy share memory fail.\n"); return 0; } return 1; }
2、shm_test2.c
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <sys/un.h> #include <sys/shm.h> #include <sys/types.h> #include <sys/sem.h> #include <sys/stat.h> #include <sys/socket.h> #define SEM_KEY 100 #define PRINT_TIMES 10 #define SHM_KEY 101 #define UNIX_DOMAIN "/tmp/unix_sock" typedef struct shared_use { int pktlen; unsigned char pkt[1528]; } shared_use_t; static int sem_id = 0; static int connect_fd = 0; static void *shm = NULL; static int semaphore_v() { struct sembuf sem_b; sem_b.sem_num = 0; sem_b.sem_op = 1; sem_b.sem_flg = SEM_UNDO; if (semop(sem_id, &sem_b, 1) == b0f5 -1) { return -1; } return 0; } static int semaphore_p() { struct sembuf sem_b; sem_b.sem_num = 0; sem_b.sem_op = -1; sem_b.sem_flg = SEM_UNDO; if (semop(sem_id, &sem_b, 1) == -1) { return -1; } return 0; } static int semaphore_init() { sem_id = semget((key_t)SEM_KEY, 0, 0666 | IPC_CREAT); if (sem_id == -1) { return -1; } return 0; } static int sharemmy_init(void) { int shmid; shmid = shmget((key_t)SHM_KEY, sizeof(shared_use_t), 0666 | IPC_CREAT); if (shmid == -1) { return shmid; } shm = shmat(shmid, (void *)0, 0); if (shm == (void *)-1) { return -1; } return shmid; } static int sharemmy_destroy(int shmid, void *shm) { int rv; rv = shmdt(shm); if (rv == -1) { return rv; } return 0; } static int domain_client(void) { int rv; struct sockaddr_un srv_un; connect_fd = socket(AF_UNIX, SOCK_STREAM, 0); if (connect_fd < 0) { perror("client socket: "); return -1; } memset(&srv_un, 0, sizeof(srv_un)); srv_un.sun_family = AF_UNIX; strncpy(srv_un.sun_path, UNIX_DOMAIN, sizeof(srv_un.sun_path) - 1); rv = connect(connect_fd, (struct sockaddr *)&srv_un, sizeof(srv_un)); if (rv < 0) { perror("connect: "); close(connect_fd); return -1; } return 0; } static int shmread(shared_use_t *shared) { int rv; rv = semaphore_p(); if (rv < 0) { return -1; } shared->pktlen = ((shared_use_t *)shm)->pktlen; memcpy(shared->pkt, ((shared_use_t *)shm)->pkt, shared->pktlen); rv = semaphore_v(); if (rv < 0) { return -1; } return 0; } static void print_pkt(shared_use_t shared_pkt) { int i; printf("********** RECV PACKET **********\n"); for (i = 0; i < shared_pkt.pktlen; i++) { printf("0x%02x ", shared_pkt.pkt[i]); if ((i + 1) % 16 == 0) { printf("\n"); } } printf("********** END **********\n"); printf("\n"); } int main() { int rv; int shmid; char cmd[10]; shared_use_t shared_pkt; rv = semaphore_init(); if (rv < 0) { printf("Init a semaphore fail.\n"); } shmid = sharemmy_init(); if (shmid == -1) { printf("Init a share memory fail.\n"); return 0; } usleep(10*1000); rv = domain_client(); if (rv < 0) { printf("Create domain client socket fail.\n"); return 0; } printf("Client init success.\n"); while (1) { memset(cmd, 0, 10); rv = recv(connect_fd, cmd, sizeof(cmd), 0); if (rv < 0) { printf("Recv cmd from server fail.\n"); close(connect_fd); break; } if (strstr(cmd, "send") != NULL || strstr(cmd, "Send") != NULL) { rv = shmread(&shared_pkt); if (rv < 0) { printf("Read packet from share memory fail.\n"); break; } print_pkt(shared_pkt); continue; } else if (strstr(cmd, "quit") != NULL || strstr(cmd, "Quit") != NULL) { printf("Quit the packet recv client.\n"); break; } else { printf("Unrecognized command for client.\n"); break; } } rv = sharemmy_destroy(shmid, shm); if (rv < 0) { printf("Destroy share memory fail.\n"); return 0; } close(connect_fd); return 1; }
以上两个程序实现的功能:shm_test1接收用户输入命令,如果是send则将向共享内存区域写入一个报文,并发送socket消息通知进程shm_test2从共享内存中读出报文并打印出来。
相关文章推荐
- Linux spi驱动--时钟频率
- 初识Linux系统性能分析和调优
- CentOS学习10_CentOS系统安装过程和配置细节
- linux 欢迎界面
- Linux下配置SNMP
- centos网卡错误Device eth0 does not seem to be present
- Linux自动备份MySql数据库
- linux下jdk安装
- Linux环境下MySQL-python安装过程
- 每天一个linux命令(52):ifconfig命令
- linux grep 命令
- Linux内核代码风格
- Linux日志文件总管——logrotate
- linux head 命令
- VM虚拟机中Linux扩展磁盘空间的方法
- Linux 格式化分区 报错Could not stat --- No such file or directory 和 partprobe 命令
- Linux线程简说
- centos7设置服务自启动
- Linux上实现Windows的SQLPlus保存SQL历史记录功能
- LINUX的各分区作用是什么?