网站模块是指什么地方,邢台信息港聊天室,店铺推广策略,网站推广方法技巧一、 Makefile模板
#指定生成的文件名
OJB_OUT test#指定每一个c文件对应的.o文件
OBJS a.o b.o main.o#指定编译器
CC gcc#指定需要的库
ULDFLAGS ###########################################
#以下的内容不需要修改
###########################################
all:…一、 Makefile模板
#指定生成的文件名
OJB_OUT test#指定每一个c文件对应的.o文件
OBJS a.o b.o main.o#指定编译器
CC gcc#指定需要的库
ULDFLAGS ###########################################
#以下的内容不需要修改
###########################################
all:$(OJB_OUT)$(OJB_OUT):$(OBJS)$(CC) -o $ $^ $(ULDFLAGS)dep_files : $(foreach f,$(OBJS),.$(f).d)
dep_files : $(wildcard $(dep_files))ifneq ($(dep_files),)include $(dep_files)
endif$(OBJS):%.o:%.c$(CC) -Wp,-MD,.$.d -c $ -o $clean:rm -rf .*.o.d *.o $(OJB_OUT)
二、 工程模板消息队列和共享内存
1. pub_define.h
/***********************************************************************************
Description: 类型重定义
***********************************************************************************/
#ifndef __PUB_DEFINE_H
#define __PUB_DEFINE_H#include sys/types.h
#include stdio.h
#include string.h
#include unistd.h
#include stdlib.h
#include assert.h#define MAX_PROC_NAME_SZ 32#define MAX_PATH_LEN 256 //最大路径长度#ifdef BOOL
#undef BOOL
#endif#ifdef FALSE
#undef FALSE
#endif#ifdef TRUE
#undef TRUE
#endif#define BOOL int
#define FALSE (0)
#define TRUE (!FALSE)#define KB 1024
#define MB (1024*KB)
#define GB (1024*MB)#define UNUSED(x) (void)x; //仅仅为了消除警告用可解决未定义变量#include stdint.h#define uint8 uint8_t
#define uint16 uint16_t
#define uint32 uint32_t#define int8 int8_t
#define int16 int16_t
#define int32 int32_t#define SLEEP_MS(ms) usleep(ms*1000)#define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x)))#endif //__PUB_DEFINE_H2. msg_queue_peer.h
/***********************************************************************************
Description: 点对点型消息队列组件
***********************************************************************************/#ifndef MSG_QUEUE_PEER_H
#define MSG_QUEUE_PEER_H#include pub_define.h
#include sys/ipc.h
#include sys/msg.hint msg_queue_send(const char *name, const void *msg, size_t msgsz, int msgflg);
int msg_queue_recv(const char *name, void *msg, size_t msgsz, long msgtyp, int msgflg);#endif // MSG_QUEUE_PEER_H3. shmem.h
/***********************************************************************************
Description: 提供共享内存组件
***********************************************************************************/#ifndef SHMEM_H
#define SHMEM_H#include pub_define.h
#include sys/ipc.h
#include sys/shm.h#define SHM_NAME_SZ 32struct shm_param
{int id; //共享内存IDsize_t size;void *addr; //共享内存地址char name[SHM_NAME_SZ1]; //共享内存key标识
};int shm_init(struct shm_param *para, const char *name, size_t size);
void *shm_getaddr(struct shm_param *para);
void shm_write(const struct shm_param *para, void *data, size_t size);
int shm_del(const struct shm_param *para);#endif // SHMEM_H4. msg_queue_peer.c
/***********************************************************************************
Description: 点对点型消息队列组件
***********************************************************************************/#include errno.h
#include msg_queue_peer.h#define MSG_PATH /tmp/ipc/msgqueue/peer/#define MAGIC_ID j/*** brief msg_queue_send* param name 发送给哪个消息队列* param msg 消息数据第一个字段必须是long类型的消息类型* param msgsz 整个msg大小不需要减去long--sizeof(*msg)* param msgflg 同msgsnd* return 同msgsnd*/
int msg_queue_send(const char *name, const void *msg, size_t msgsz, int msgflg)
{assert(NULL ! name strlen(name) 0);assert(NULL ! msg);key_t key;int ret;int msgid;char sys_cmd[256];char path[256];sprintf(path, %s%s, MSG_PATH, name);//文件不存在创建if(access(path, F_OK) 0){sprintf(sys_cmd, %s %s, touch, path);ret system(sys_cmd);UNUSED(ret);}//创建keykey ftok(path, MAGIC_ID);if(key 0){perror(fail to ftok);return -1;}//创建消息队列msgid msgget(key, IPC_CREAT|0666);if (msgid 0){perror(fail to msgget);return -1;}return msgsnd(msgid, msg, msgsz - sizeof(long), msgflg);
}/*** brief msg_queue_send* param name 从哪个消息队列接收* param msg 消息缓冲区第一个字段必须是long类型的消息类型* param msgsz 整个msg大小不需要减去long--sizeof(*msg)* param msgtyp 同msgrcv* param msgflg 同msgrcv* return 同msgrcv*/
int msg_queue_recv(const char *name, void *msg, size_t msgsz, long msgtyp, int msgflg)
{assert(NULL ! name strlen(name) 0);assert(NULL ! msg);key_t key;int ret;int msgid;char sys_cmd[256];char path[256];sprintf(path, %s%s, MSG_PATH, name);//文件不存在创建if(access(path, F_OK) 0){sprintf(sys_cmd, %s %s, touch, path);ret system(sys_cmd);UNUSED(ret);}//创建keykey ftok(path, MAGIC_ID);if(key 0){perror(fail to ftok);return -1;}//创建消息队列msgid msgget(key, IPC_CREAT|0666);if (msgid 0){perror(fail to msgget);return -1;}return msgrcv(msgid, msg, msgsz - sizeof(long), msgtyp, msgflg);
}/*** brief 判断某个类型的消息是否存在但是不取出* param name 指定消息队列名* param msgtyp 消息类型* return TRUE FALSE*/
BOOL msg_queue_msgexist(const char *name, long msgtyp)
{assert(NULL ! name strlen(name) 0);key_t key;int ret;int msgid;char sys_cmd[256];char path[256];sprintf(path, %s%s, MSG_PATH, name);//文件不存在创建if(access(path, F_OK) 0){sprintf(sys_cmd, %s %s, touch, path);ret system(sys_cmd);UNUSED(ret);}//创建keykey ftok(path, MAGIC_ID);if(key 0){perror(fail to ftok);return -1;}//创建消息队列msgid msgget(key, IPC_CREAT|0666);if (msgid 0){perror(fail to msgget);return -1;}if(msgrcv(msgid, NULL, 0, msgtyp, IPC_NOWAIT) 0){if(errno E2BIG){return TRUE;}}return FALSE;
} 5. shmem.c
/***********************************************************************************
Description: 提供共享内存组件
***********************************************************************************/#include shmem.h#define MAGIC_ID j/*** brief 初始化共享内存* param para 参数结构体传入即可* param name 共享内存标识名称* return 0 -1*/
int shm_init(struct shm_param *para, const char *name, size_t size)
{assert(NULL ! para);assert(NULL ! name strlen(name) 0);key_t key;int ret;int id;char sys_cmd[256];char path[256];sprintf(path, /tmp/ipc/shmem/%s, name);sprintf(sys_cmd, %s %s, touch, path);ret system(sys_cmd);UNUSED(ret);//创建keykey ftok(path, MAGIC_ID);if(key 0){perror(fail to ftok);printf(error :path %s\n, path);return -1;}//创建共享内存id shmget(key, size, IPC_CREAT|0666);if (id 0){perror(fail to shmget);return -1;}para-id id;para-size size;strcpy(para-name, name);return 0;
}/*** brief 获取共享内存地址* param para* return 失败返回NULL*/
void *shm_getaddr(struct shm_param *para)
{void *addr;addr shmat(para-id, NULL, 0);if(addr (void *)-1){para-addr NULL;}else{para-addr addr;}return para-addr;
}/*** brief 写共享内存* param para* param data* param size*/
void shm_write(const struct shm_param *para, void *data, size_t size)
{assert(size para-size);assert(NULL ! data);memcpy(para-addr, data, size);
}/*** brief 解除共享内存* param para* return*/
int shm_del(const struct shm_param *para)
{assert(NULL ! para);int ret shmdt(para-addr);if(ret 0){perror(fail to shmdt);return -1;}ret shmctl(para-id, IPC_RMID, NULL);if(ret 0){perror(fail to shmctl);return -1;}return 0;
}6. main.c
#include stdio.hint main(int argc, char *argv[])
{printf(project demo\n);return 0;
}
7. Makefile
#指定生成的文件名
OJB_OUT test#指定每一个c文件对应的.o文件
OBJS shmem.o msg_queue_peer.o main.o#指定编译器
CC gcc#指定需要的库和路径
ULDFLAGS ###########################################
#以下的内容不需要修改
###########################################
all:$(OJB_OUT)$(OJB_OUT):$(OBJS)$(CC) -o $ $^ $(ULDFLAGS)dep_files : $(foreach f,$(OBJS),.$(f).d)
dep_files : $(wildcard $(dep_files))ifneq ($(dep_files),)include $(dep_files)
endif$(OBJS):%.o:%.c$(CC) -Wp,-MD,.$.d -c $ -o $clean:rm -rf .*.o.d *.o $(OJB_OUT)
三、工程模板中通信组件的使用
以下组件依赖临时目录必须提前创建tmp目录是内存型目录如果重启了系统会消失所以每次重启后注意重新创建下
mkdir /tmp/ipc/shmem -p
mkdir /tmp/ipc/msgqueue/peer -p
1. 消息队列
源码阅读
1发送程序
#include msg_queue_peer.hstruct msgbuf
{long mtype;char mdata[256];
};int main(int argc, char *argv[])
{struct msgbuf send_buf;//这个mtype可以不用但是必须赋一个不小于0的数send_buf.mtype 1;while (1){gets(send_buf.mdata, 256);if(msg_queue_send(topic, send_buf, sizeof(send_buf), 0) 0){printf(msg_queue_send error\n);return -1;}}return 0;
}
2接收程序
#include msg_queue_peer.hstruct msgbuf
{long mtype;char mdata[256];
};int main(int argc, char *argv[])
{struct msgbuf recv_buf;while (1){if(msg_queue_recv(topic, recv_buf, sizeof(recv_buf), 0, 0) 0){printf(recv from msga type %ld\n, recv_buf.mtype);printf(recv from msga data %s\n, recv_buf.mdata);}else{perror(recv error:);return -1;}}return 0;
}
2. 共享内存
1写入共享内存
#include shmem.hstatic struct shm_param para;struct student
{int num;char name[64];
};int main(int argc, char *argv[])
{int ret -1;ret shm_init(para, shm_test, 1024);if(ret 0){return -1;}struct student *addr shm_getaddr(para);if(addr NULL){return -1;}addr-num 10;strcpy(addr-name, zhangsan);return 0;
}
2读取共享内存
#include shmem.hstatic struct shm_param para;struct student
{int num;char name[64];
};int main(int argc, char *argv[])
{int ret -1;ret shm_init(para, shm_test, 1024);if(ret 0){return -1;}struct student *addr shm_getaddr(para);if(addr NULL){return -1;}printf(num %d\n, addr-num);printf(num %s\n, addr-name);shm_del(para);return 0;
}
3. 共享内存中读写结构体数组的使用 假设学生信息结构体定义如下
struct student
{int num;char name[16];
}
定义a、b两个进程a进程创建若干个个数自己决定是可变的学生填充任意的信息通过共享内存将学生信息共享给b进程包括学生个数。b进程拿到信息后打印到终端。
提示这里可巧妙的利用指针的操作先申请足够大的共享内存映射后然后通过不同类型的指针来操作和读取内容中的数据。模型图如下 1共享内存写入结构体数组和大小
#include shmem.hstatic struct shm_param para;struct student
{int num;char name[64];
};static int *total; //指向共享内存中数据节点总个数
static struct student *node_arr; //指向共享内存中节点缓存数组头#define MAX_NODE 128 //最大支持学生数目
#define STD_NODE_LEN sizeof(struct student)
#define MAX_NODE_SIZE (MAX_NODE * STD_NODE_LEN)int main(int argc, char *argv[])
{int ret -1;ret shm_init(para, shm_test, MAX_NODE_SIZE);if(ret 0){return -1;}void *node_p shm_getaddr(para);if(node_p NULL){return -1;}memset(node_p, 0, MAX_NODE_SIZE);//前4个字节存储实际的学生数目total (int *)node_p;//后面空间存储数据点node_arr (struct student *)(node_p sizeof(int));*total 3; //假设有3个人//第1个人赋值node_arr[0].num 1;strcpy(node_arr[0].name, zhangsan);//第2个人赋值node_arr[1].num 2;strcpy(node_arr[1].name, lisi);//第3个人赋值node_arr[2].num 3;strcpy(node_arr[2].name, wangwu);return 0;
}2共享内存读取结构体数组
#include shmem.hstatic struct shm_param para;struct student
{int num;char name[64];
};static int *total; //指向共享内存中数据节点总个数
static struct student *node_arr; //指向共享内存中节点缓存数组头#define MAX_NODE 128 //最大支持学生数目
#define STD_NODE_LEN sizeof(struct student)
#define MAX_NODE_SIZE (MAX_NODE * STD_NODE_LEN)int main(int argc, char *argv[])
{int ret -1;ret shm_init(para, shm_test, MAX_NODE_SIZE);if(ret 0){return -1;}void *node_p shm_getaddr(para);if(node_p NULL){return -1;}//前4个字节存储实际的学生数目total (int *)node_p;//后面空间存储数据点node_arr (struct student *)(node_p sizeof(int));printf(num %d\n, *total);int i;for(i0; i*total; i){printf(num%d, name%s\n, \node_arr[i].num,\node_arr[i].name);}//这个接口只有在这块共享内存不用了才能删除项目中如果一直使用不要调用这个接口shm_del(para);return 0;
}