1、概述
这里用到了线程的相关知识,包括线程的创建pthread _create()、线程的回收pthread_join()、线程的结束pthread_exit()
项目中根据实际情况开辟了相关的线程,比如:
pthread_client_request(void *arg)-----------接收用户请求线程
pthread_refresh(void *arg)--------------------数据刷新线程
pthread_sqlite(void *arg)----------------------数据库线程,保存数据库的数据
pthread_transfer(void *arg)-------------------数据采集线程
pthread_buzzer(void *arg)--------------------蜂鸣器控制线程
pthread_led(void *arg)-------------------------led灯控制线程
pthread_seg(void *arg)------------------------led灯模拟数码管控制线程
pthread_fan(void *arg)-------------------------zigbee风扇控制线程
数据的下发
pthread_client_request()与pthread_buzzer()、pthread_led()线程之间的通讯是通过全局变量+互斥+条件变量来实现的;
从网页发送消息到A9是通过消息队列来实现的,这里就用到了消息队列的知识点,包括消息队列的创建(msgget)、接收消息(msgrcv)、发送消息(msgsnd)、控制消息队列(msgctl);
数据的上传
pthread_refresh()与env.cgi进程间的通讯是通过共享内存+信号量来实现同步操作的;
从A9刷新数据到网页是通过共享内存来实现的,这里就用到了共享内存的知识点,包括共享内存的创建(shmget)、映射(shmat)、撤销映射(shmdt)、共享内存控制(shmctl);同时要加上信号量P(sem_wait() )、V(sem_post())操作进行临界资源同步操作
2、主要文件
data_global.h
#ifndef __DATA_GLOBAL__H__
#define __DATA_GLOBAL__H__
/*
全局的宏定义#define
全局的线程函数声明
全局的设备节点声明
全局的消息队列发送函数外部extern声明
全局的消息队列传递的结构体信息声明
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <signal.h>
#include <pthread.h>
#include <termios.h>
#include <syscall.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/msg.h>
#include <sys/sem.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <linux/fs.h>
#include <linux/ioctl.h>
#include <stdint.h>
#include <unistd.h>
#include <errno.h>
#include <linux/input.h>
#include <errno.h>
/*********************************************************
全局的宏定义
*********************************************************/
#define MONITOR_NUM 1
#define QUEUE_MSG_LEN 32
/********************************************************
对所使用设备的定义
********************************************************/
#define ZIGBEE_DEV "/dev/ttyUSB0"
#define BEEPER_DEV "/dev/fs4412_beep"
#define LED_DEV "/dev/fsled0"
#define ADC_DEV "/dev/fsadc0"
#define MPU6050_DEV "/dev/fsmpu60500"
unsigned char cmd_led;
unsigned char cmd_buzzer;
unsigned char cmd_seg;
unsigned char cmd_fan;
/*********************************************************
全局的结构体声明
*********************************************************/
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
/*zigbee所采集的数据*/
struct makeru_zigbee_info{
uint8_t head[3]; //标识位: 'm' 's' 'm' makeru-security-monitor
uint8_t type; //数据类型 'z'---zigbee 'a'---a9
float temperature; //温度
float humidity; //湿度
float tempMIN; //温度下限
float tempMAX; //温度上限
float humidityMIN; //湿度下限
float humidityMAX; //湿度上限
uint32_t reserved[2]; //保留扩展位,默认填充0
};
/*a9采集的数据*/
struct makeru_a9_info{
uint8_t head[3]; //标识位: 'm' 's' 'm' makeru-security-monitor
uint8_t type; //数据类型 'z'---zigbee 'a'---a9
float adc; //电压数据
short gyrox; //陀螺仪数据
short gyroy;
short gyroz;
short aacx; //加速计数据
short aacy;
short aacz;
uint32_t reserved[2]; //保留扩展位,默认填充0
};
/*环境信息*/
struct makeru_env_data{
struct makeru_a9_info a9_info;
struct makeru_zigbee_info zigbee_info;
uint32_t reserved[2];
};
//所有房间的信息结构体
struct env_info_client_addr
{
struct makeru_env_data monitor_no[MONITOR_NUM]; //数组 home1 home2
}__attribute__((aligned (1)));
//GNU使用__attribute__选项来设置 此处设置一字节对齐
/*********************************************************
全局的外部线程函数声明
*********************************************************/
extern void *pthread_client_request(void *arg); //接收用户请求线程
extern void *pthread_refresh(void *arg); //数据刷新线程
extern void *pthread_sqlite(void *arg); //数据库线程,保存数据库的数据
extern void *pthread_transfer(void *arg); //数据采集线程
extern void *pthread_buzzer(void *arg); //蜂鸣器控制线程
extern void *pthread_led(void *arg); //led灯控制线程
extern void *pthread_seg(void *arg); //led灯模拟数码管控制线程
extern void *pthread_fan(void *arg); //zigbee风扇控制线程
//发送消息队列
extern int send_msg_queue(long type,unsigned char text);
/*********************************************************
全局的消息队列传递的结构体声明
*********************************************************/
//消息队列结构体
struct msg
{
long type; //从消息队列接收消息时用于判断的消息类型
long msgtype; //具体的消息类型
unsigned char text[QUEUE_MSG_LEN];//消息正文
};
#endif
data_global.c
/********************************************
全局的互斥体声明
全局的条件锁声明声明
全局的id和key信息声明
全局的消息队列发送函数声明
********************************************/
#include "data_global.h"
/*互斥量声明*/
pthread_mutex_t mutex_client_request,
mutex_refresh,
mutex_sqlite,
mutex_transfer,
mutex_fan,
mutex_zigbee,
mutex_buzzer,
mutex_debug,
mutex_camera,
mutex_led;
/*条件变量声明*/
pthread_cond_t cond_client_request,
cond_refresh,
cond_sqlite,
cond_transfer,
cond_fan,
cond_zigbee,
cond_buzzer,
cond_led,
cond_debug;
/*消息队列ID*/
int msgid;
/*共享内存ID*/
int shmid;
/*信号灯集ID*/
int semid;
key_t key; //msg_key
key_t shm_key;
key_t sem_key;
/*所有房间环境信息*/
struct env_info_client_addr sm_all_env_info;
//发送消息队列
int send_msg_queue(long type,unsigned char text)
{
struct msg msgbuf;
msgbuf.type = 1L;
msgbuf.msgtype = type;
msgbuf.text[0] = text;
if(msgsnd(msgid,&msgbuf,sizeof(msgbuf) - sizeof(long),0) == -1){
perror("fail to msgsnd type2");
exit(1);
}
return 0;
}
mian.c
#include "data_global.h"
void release_pthread_resource(int signo);
/*互斥量声明*/
extern pthread_mutex_t mutex_client_request,
mutex_refresh,
mutex_sqlite,
mutex_transfer,
mutex_fan,
mutex_zigbee,
mutex_buzzer,
mutex_debug,
mutex_led;
/*条件变量声明*/
extern pthread_cond_t cond_client_request,
cond_refresh,
cond_sqlite,
cond_transfer,
cond_transfer,
cond_fan,
cond_zigbee,
cond_buzzer,
cond_debug,
cond_led;
/*消息队列ID*/
extern int msgid;
/*共享内存ID*/
extern int shmid;
/*信号灯集ID*/
extern int semid;
pthread_t id_client_request,
id_refresh,
id_sqlite,
id_transfer,
id_fan,
id_buzzer,
id_led;
int main(int argc, const char *argv[])
{
/*互斥锁初始化*/
pthread_mutex_init(&mutex_client_request,NULL);
pthread_mutex_init(&mutex_refresh,NULL);
pthread_mutex_init(&mutex_sqlite,NULL);
pthread_mutex_init(&mutex_transfer,NULL);
pthread_mutex_init(&mutex_fan,NULL);
pthread_mutex_init(&mutex_zigbee,NULL);
pthread_mutex_init(&mutex_buzzer,NULL);
pthread_mutex_init(&mutex_debug,NULL);
pthread_mutex_init(&mutex_led,NULL);
//等待接受信号,信号处理函数
/*收到终止信号,释放线程资源
SIGINT----CTRL C
release_pthread_resource----释放线程资源函数
*/
signal (SIGINT, release_pthread_resource);
/*初始化条件变量*/
pthread_cond_init(&cond_client_request,NULL);
pthread_cond_init(&cond_refresh,NULL);
pthread_cond_init(&cond_sqlite,NULL);
pthread_cond_init(&cond_transfer,NULL);
pthread_cond_init(&cond_fan,NULL);
pthread_cond_init(&cond_zigbee,NULL);
pthread_cond_init(&cond_buzzer,NULL);
pthread_cond_init(&cond_debug,NULL);
pthread_cond_init(&cond_led,NULL);
/*创建线程*/
pthread_create(&id_client_request, NULL,pthread_client_request,NULL);
pthread_create(&id_refresh, NULL,pthread_refresh,NULL);
pthread_create(&id_sqlite, NULL,pthread_sqlite,NULL);
pthread_create(&id_transfer, NULL,pthread_transfer,NULL);
pthread_create(&id_fan, NULL,pthread_fan,NULL);
pthread_create(&id_buzzer, NULL,pthread_buzzer,NULL);
pthread_create(&id_led, NULL,pthread_led,NULL);
/*等待线程结束回收线程*/
pthread_join(id_client_request,NULL); printf ("pthread1\n");
pthread_join(id_refresh,NULL); printf ("pthread2\n");
pthread_join(id_sqlite,NULL); printf ("pthread3\n");
pthread_join(id_transfer,NULL); printf ("pthread4\n");
pthread_join(id_fan,NULL); printf ("pthread5\n");
pthread_join(id_buzzer,NULL); printf ("pthread6\n");
pthread_join(id_led,NULL); printf ("pthread7\n");
return 0;
}
void release_pthread_resource(int signo)
{
/*释放锁*/
pthread_mutex_destroy (&mutex_client_request);
pthread_mutex_destroy (&mutex_refresh);
pthread_mutex_destroy (&mutex_sqlite);
pthread_mutex_destroy (&mutex_transfer);
pthread_mutex_destroy (&mutex_fan);
pthread_mutex_destroy (&mutex_zigbee);
pthread_mutex_destroy (&mutex_buzzer);
pthread_mutex_destroy (&mutex_debug);
pthread_mutex_destroy (&mutex_led);
/*释放条件变量*/
pthread_cond_destroy (&cond_client_request);
pthread_cond_destroy (&cond_refresh);
pthread_cond_destroy (&cond_sqlite);
pthread_cond_destroy (&cond_transfer);
pthread_cond_destroy (&cond_fan);
pthread_cond_destroy (&cond_zigbee);
pthread_cond_destroy (&cond_buzzer);
pthread_cond_destroy (&cond_debug);
pthread_cond_destroy (&cond_led);
/*回收线程———线程分离*/
pthread_detach(id_client_request);
pthread_detach(id_refresh);
pthread_detach(id_sqlite);
pthread_detach(id_transfer);
pthread_detach(id_fan);
pthread_detach(id_buzzer);
pthread_detach(id_led);
printf("all pthread is detached\n");
/*删除消息队列*/
msgctl(msgid, IPC_RMID, NULL);
/*删除共享内存*/
shmctl(shmid, IPC_RMID, NULL);
/*删除信号灯*/
semctl(semid, 1, IPC_RMID, NULL);
exit(0);
}