目录
一、pthread线程间的同步互斥
线程间同步互斥的操作:
1、线程间同步 ==== 有序执行
1、多个信号量
2、条件变量+互斥锁 ===>broadcast signal
2、线程间互斥 ==== "你死我活"
1、单个信号量
2、互斥锁
同步和互斥是为了什么?
为了保护临界资源
什么是临界资源:
全局变量
pthread_create之前的成为 全局资源 =====>当有线程操作全局资源的时候 ===>变为临界资源
/*************************************************************************
# FileName : pthreadsem.c
# Author : fengjunhui
# Email : 18883765905@163.com
************************************************************************/
#include<stdio.h>
#include <pthread.h>
#include <semaphore.h>
#define N 64
typedef struct message{
char buf[N];
int len;
}msg_t;
sem_t sem_reverse;
sem_t sem_printf;
void* reverse_msgbuf(void* arg)
{
msg_t *msg = (msg_t *)arg;
int i = 0;
char tmp;
while(1){
sem_wait(&sem_reverse);
printf("reverse_msgbuf -------------\n");
//printf("hello reverse_msgbuf.\n");
#if 1
for(i = 0; i < msg->len/2; i ++){
tmp = msg->buf[i];
msg->buf[i] = msg->buf[msg->len - i - 1];
msg->buf[msg->len - i -1] = tmp;
}
#endif
sleep(1);
printf("reverse_msgbuf :%s\n",msg->buf);
sem_post(&sem_printf);
}
}
void* printf_msgbuf(void* arg)
{
msg_t *msg = (msg_t *)arg;
while(1){
sem_wait(&sem_printf);
printf("printf_msgbuf :***********\n");
printf("printf_msgbuf :%s\n",msg->buf);
sem_post(&sem_reverse);
}
}
int main(int argc, const char *argv[])
{
msg_t msg = {"123456789",9};
pthread_t tid[2];
sem_init(&sem_reverse,0,1);
sem_init(&sem_printf,0,0);
pthread_create(&tid[0],NULL,reverse_msgbuf,(void *)&msg);
pthread_create(&tid[1],NULL,printf_msgbuf,(void *)&msg);
pause();
return 0;
}
/*************************************************************************
# FileName : flaglock.c
# Author : fengjunhui
# Email : 18883765905@163.com
************************************************************************/
#include<stdio.h>
#include <pthread.h>
#define N 64
typedef struct message{
char buf[N];
int len;
}msg_t;
pthread_mutex_t mymutex;
void* reverse_msgbuf(void* arg)
{
msg_t *msg = (msg_t *)arg;
int i = 0;
char tmp;
while(1){
pthread_mutex_lock(&mymutex);
for(i = 0; i < msg->len/2; i ++){
tmp = msg->buf[i];
msg->buf[i] = msg->buf[msg->len - i - 1];
msg->buf[msg->len - i -1] = tmp;
}
pthread_mutex_unlock(&mymutex);
}
}
void* printf_msgbuf(void* arg)
{
msg_t *msg = (msg_t *)arg;
while(1){
pthread_mutex_lock(&mymutex);
printf("buf :%s\n",msg->buf);
pthread_mutex_unlock(&mymutex);
sleep(1);
}
}
int main(int argc, const char *argv[])
{
msg_t msg = {"123456789",9};
pthread_t tid[2];
pthread_mutex_init(&mymutex,NULL);
pthread_create(&tid[0],NULL,reverse_msgbuf,(void *)&msg);
pthread_create(&tid[1],NULL,printf_msgbuf,(void *)&msg);
pause();
return 0;
}
/*************************************************************************
# FileName : flaglock.c
# Author : fengjunhui
# Email : 18883765905@163.com
************************************************************************/
#include<stdio.h>
#include <pthread.h>
#define N 64
typedef struct message{
char buf[N];
int len;
// int busy_flag;
}msg_t;
int flag = 0;
pthread_mutex_t mymutex;
pthread_cond_t mycond = PTHREAD_COND_INITIALIZER;
void* reverse_msgbuf(void* arg)
{
msg_t *msg = (msg_t *)arg;
int i = 0;
char tmp;
while(1){
pthread_mutex_lock(&mymutex);
printf("reverse_msgbuf -------------\n");
while(flag != 0){
pthread_cond_wait(&mycond,&mymutex);
}
//printf("hello reverse_msgbuf.\n");
#if 1
for(i = 0; i < msg->len/2; i ++){
tmp = msg->buf[i];
msg->buf[i] = msg->buf[msg->len - i - 1];
msg->buf[msg->len - i -1] = tmp;
}
#endif
printf("reverse_msgbuf :%s\n",msg->buf);
flag = 1;
pthread_mutex_unlock(&mymutex);
pthread_cond_broadcast(&mycond);
}
}
void* printf_msgbuf(void* arg)
{
msg_t *msg = (msg_t *)arg;
while(1){
pthread_mutex_lock(&mymutex);
printf("printf_msgbuf :***********\n");
while(flag != 1){
pthread_cond_wait(&mycond,&mymutex);
}
printf("printf_msgbuf :%s\n",msg->buf);
flag = 0;
pthread_mutex_unlock(&mymutex);
pthread_cond_broadcast(&mycond);
}
}
int main(int argc, const char *argv[])
{
//msg_t msg = {"123456789",9,0};
msg_t msg = {"123456789",9};
pthread_t tid[2];
pthread_cond_init(&mycond,NULL);
pthread_mutex_init(&mymutex,NULL);
pthread_create(&tid[0],NULL,reverse_msgbuf,(void *)&msg);
pthread_create(&tid[1],NULL,printf_msgbuf,(void *)&msg);
pause();
return 0;
}
/*************************************************************************
# FileName : flaglock.c
# Author : fengjunhui
# Email : 18883765905@163.com
************************************************************************/
#include<stdio.h>
#include <pthread.h>
#define N 64
typedef struct message{
char buf[N];
int len;
// int busy_flag;
}msg_t;
pthread_mutex_t mymutex;
pthread_cond_t mycond_reverse = PTHREAD_COND_INITIALIZER;
pthread_cond_t mycond_printf = PTHREAD_COND_INITIALIZER;
void* reverse_msgbuf(void* arg)
{
msg_t *msg = (msg_t *)arg;
int i = 0;
char tmp;
while(1){
pthread_mutex_lock(&mymutex);
pthread_cond_wait(&mycond_reverse,&mymutex);
printf("reverse_msgbuf -------------\n");
#if 1
for(i = 0; i < msg->len/2; i ++){
tmp = msg->buf[i];
msg->buf[i] = msg->buf[msg->len - i - 1];
msg->buf[msg->len - i -1] = tmp;
}
#endif
printf("reverse_msgbuf :%s\n",msg->buf);
pthread_mutex_unlock(&mymutex);
}
}
void* printf_msgbuf(void* arg)
{
msg_t *msg = (msg_t *)arg;
while(1){
pthread_mutex_lock(&mymutex);
pthread_cond_wait(&mycond_printf,&mymutex);
printf("printf_msgbuf :***********\n");
printf("printf_msgbuf :%s\n",msg->buf);
pthread_mutex_unlock(&mymutex);
}
}
int main(int argc, const char *argv[])
{
//msg_t msg = {"123456789",9,0};
msg_t msg = {"123456789",9};
pthread_t tid[2];
pthread_cond_init(&mycond_printf,NULL);
pthread_cond_init(&mycond_reverse,NULL);
pthread_mutex_init(&mymutex,NULL);
pthread_create(&tid[0],NULL,reverse_msgbuf,(void *)&msg);
pthread_create(&tid[1],NULL,printf_msgbuf,(void *)&msg);
while(1){
pthread_cond_signal (&mycond_printf);
sleep(1);
pthread_cond_signal (&mycond_reverse);
sleep(1);
}
pause();
return 0;
}
二、具体实现
由于没用到sqlite并且忘记设置风扇的锁了,所以先借用了一下。
nice成功了
下面是执行控制功能的客户端线程
#include "data_global.h"
#include "buzzer.h"
#include "linuxuart.h"
extern int msgid;
extern key_t key;
extern pthread_mutex_t mutex_client_request,
mutex_refresh,
mutex_sqlite,
mutex_transfer,
mutex_analysis,
mutex_sms,
mutex_buzzer,
mutex_led,
mutex_camera;
extern pthread_cond_t cond_client_request,
cond_refresh,
cond_sqlite,
cond_transfer,
cond_analysis,
cond_sms,
cond_buzzer,
cond_led,
cond_camera;
extern unsigned char cmd_led;
extern unsigned char cmd_buzzer;
extern unsigned char cmd_seg;
extern unsigned char cmd_fan;
extern char recive_phone[12] ;
extern char center_phone[12] ;
struct msg msgbuf;
//��2N��Ԫ�ر�ʾ���� ��2N+1��Ԫ�ر�ʾ��������ʱ��
unsigned char MUSIC[500] ={
//ף��ƽ��
0x26,0x20,0x20,0x20,0x20,0x20,0x26,0x10,0x20,0x10,0x20,0x80,0x26,0x20,0x30,0x20,
0x30,0x20,0x39,0x10,0x30,0x10,0x30,0x80,0x26,0x20,0x20,0x20,0x20,0x20,0x1c,0x20,
0x20,0x80,0x2b,0x20,0x26,0x20,0x20,0x20,0x2b,0x10,0x26,0x10,0x2b,0x80,0x26,0x20,
0x30,0x20,0x30,0x20,0x39,0x10,0x26,0x10,0x26,0x60,0x40,0x10,0x39,0x10,0x26,0x20,
0x30,0x20,0x30,0x20,0x39,0x10,0x26,0x10,0x26,0x80,0x26,0x20,0x2b,0x10,0x2b,0x10,
0x2b,0x20,0x30,0x10,0x39,0x10,0x26,0x10,0x2b,0x10,0x2b,0x20,0x2b,0x40,0x40,0x20,
0x20,0x10,0x20,0x10,0x2b,0x10,0x26,0x30,0x30,0x80,0x18,0x20,0x18,0x20,0x26,0x20,
0x20,0x20,0x20,0x40,0x26,0x20,0x2b,0x20,0x30,0x20,0x30,0x20,0x1c,0x20,0x20,0x20,
0x20,0x80,0x1c,0x20,0x1c,0x20,0x1c,0x20,0x30,0x20,0x30,0x60,0x39,0x10,0x30,0x10,
0x20,0x20,0x2b,0x10,0x26,0x10,0x2b,0x10,0x26,0x10,0x26,0x10,0x2b,0x10,0x2b,0x80,
0x18,0x20,0x18,0x20,0x26,0x20,0x20,0x20,0x20,0x60,0x26,0x10,0x2b,0x20,0x30,0x20,
0x30,0x20,0x1c,0x20,0x20,0x20,0x20,0x80,0x26,0x20,0x30,0x10,0x30,0x10,0x30,0x20,
0x39,0x20,0x26,0x10,0x2b,0x10,0x2b,0x20,0x2b,0x40,0x40,0x10,0x40,0x10,0x20,0x10,
0x20,0x10,0x2b,0x10,0x26,0x30,0x30,0x80,0x00,
#if 0
0x30,0x1c,0x10,0x20,0x40,0x1c,0x10,0x18,0x10,0x20,0x10,0x1c,0x10,0x18,0x40,0x1c,
0x20,0x20,0x20,0x1c,0x20,0x18,0x20,0x20,0x80,0xff,0x20,0x30,0x1c,0x10,0x18,0x20,
0x15,0x20,0x1c,0x20,0x20,0x20,0x26,0x40,0x20,0x20,0x2b,0x20,0x26,0x20,0x20,0x20,
0x30,0x80,0xff,0x20,0x20,0x1c,0x10,0x18,0x10,0x20,0x20,0x26,0x20,0x2b,0x20,0x30,
0x20,0x2b,0x40,0x20,0x20,0x1c,0x10,0x18,0x10,0x20,0x20,0x26,0x20,0x2b,0x20,0x30,
0x20,0x2b,0x40,0x20,0x30,0x1c,0x10,0x18,0x20,0x15,0x20,0x1c,0x20,0x20,0x20,0x26,
0x40,0x20,0x20,0x2b,0x20,0x26,0x20,0x20,0x20,0x30,0x80,0x20,0x30,0x1c,0x10,0x20,
0x10,0x1c,0x10,0x20,0x20,0x26,0x20,0x2b,0x20,0x30,0x20,0x2b,0x40,0x20,0x15,0x1f,
0x05,0x20,0x10,0x1c,0x10,0x20,0x20,0x26,0x20,0x2b,0x20,0x30,0x20,0x2b,0x40,0x20,
0x30,0x1c,0x10,0x18,0x20,0x15,0x20,0x1c,0x20,0x20,0x20,0x26,0x40,0x20,0x20,0x2b,
0x20,0x26,0x20,0x20,0x20,0x30,0x30,0x20,0x30,0x1c,0x10,0x18,0x40,0x1c,0x20,0x20,
0x20,0x26,0x40,0x13,0x60,0x18,0x20,0x15,0x40,0x13,0x40,0x18,0x80,0x00,
#endif
};
void *pthread_client_request(void *arg)
{
if((key = ftok("/tmp",'g')) < 0){
perror("ftok failed .\n");
exit(-1);
}
msgid = msgget(key,IPC_CREAT|IPC_EXCL|0666);
if(msgid == -1) {
if(errno == EEXIST){
msgid = msgget(key,0777);
}else{
perror("fail to msgget");
exit(1);
}
}
printf("pthread_client_request\n");
while(1){
bzero(&msgbuf,sizeof(msgbuf));
printf("wait form client request...\n");
msgrcv (msgid, &msgbuf, sizeof (msgbuf) - sizeof (long), 1L, 0);
printf ("Get %ldL msg\n", msgbuf.msgtype);
printf ("text[0] = %#x\n", msgbuf.text[0]);
switch(msgbuf.msgtype){
case 1L:
pthread_mutex_lock(&mutex_led);
printf("hello led\n");
cmd_led = msgbuf.text[0];
pthread_mutex_unlock(&mutex_led);
pthread_cond_signal(&cond_led);
break;
case 2L:
printf("beep\n");
pthread_mutex_lock(&mutex_sqlite);
printf("hello beep\n");
cmd_buzzer = msgbuf.text[0];
printf("cmd_buzzer :%#x.\n",cmd_buzzer);
int i = 0;
int buzzer_fd;
beep_desc_t beeper;
buzzer_fd = open(BEEPER_DEV,O_RDWR | O_NONBLOCK);
if ( buzzer_fd == -1 ) {
perror("open beeper failed.\n");
//return -1;
}
printf("buzzer_fd ;%d.\n",buzzer_fd);
if(cmd_buzzer == 0x51){
ioctl(buzzer_fd,BEEP_ON);
#if 1
for(i = 0;i < sizeof(MUSIC)/sizeof(MUSIC[0]); i += 2)
{
beeper.tcnt = MUSIC[i];
beeper.tcmp = MUSIC[i]/2;
ioctl(buzzer_fd,BEEP_FREQ,&beeper);
usleep(MUSIC[i+1] * 20000);
} //��ʱ���������������̵߳Ĵ��������б�����ʱ����
printf("music play over....\n");
close(buzzer_fd);
#endif
}else if(cmd_buzzer == 0x50){
ioctl(buzzer_fd,BEEP_OFF);
}else {
printf("cmd_buzzer error.\n");
}
pthread_mutex_unlock(&mutex_sqlite);
break;
case 3L:
pthread_mutex_lock(&mutex_led);
printf("hello seg\n");
cmd_seg = msgbuf.text[0];
pthread_mutex_unlock(&mutex_led);
pthread_cond_signal(&cond_led);
break;
case 4L:
pthread_mutex_lock(&mutex_sqlite);
printf("hello fan\n");
cmd_fan = msgbuf.text[0];
int fan_fd = open_port("/dev/ttyUSB0"); //�����豸
if(fan_fd < 0){
printf("open failed\n");
}
set_com_config(fan_fd, 115200, 8, 'N', 1); //���ô��ڲ���
char cmdbuf[4] = {0};
if(cmd_fan == 0x21){
strcpy(cmdbuf,"1\n"); //ע����
write(fan_fd,cmdbuf,sizeof(cmdbuf)/sizeof(cmdbuf[0]));
sleep(2);
}
if(cmd_fan == 0x20){
strcpy(cmdbuf,"0\n");
write(fan_fd,cmdbuf,sizeof(cmdbuf)/sizeof(cmdbuf[0]));
sleep(2);
}
char buf[32] = {0};
//get data from zigbee
read(fan_fd,&buf,sizeof(buf));
printf("sizeof(buf) = %d.\n",sizeof(buf));
printf(">>>>>>%s\n",buf);
sleep(1);
pthread_mutex_unlock(&mutex_sqlite);
break;
case 5L:
printf("set env data\n");
printf("temMAX: %d\n",*((int *)&msgbuf.text[1]));
printf("temMIN: %d\n",*((int *)&msgbuf.text[5]));
printf("humMAX: %d\n",*((int *)&msgbuf.text[9]));
printf("humMAX: %d\n",*((int *)&msgbuf.text[13]));
printf("illMAX: %d\n",*((int *)&msgbuf.text[17]));
printf("illMAX: %d\n",*((int *)&msgbuf.text[21]));
break;
case 6L:
case 7L:
case 8L:
case 9L:
printf("�����Խ���Щ��Ϊ��չ��ѧϰ������.\n");
break;
case 10L:
{
pthread_mutex_lock (&mutex_sms);
int i = 0 , j = 0 ;
for(i = 0 ; i < 11; i++){
recive_phone[i] = msgbuf.text[i];
}
recive_phone[i] = '\0';
printf("recive:%s\n",recive_phone);
for(j = 0 ;msgbuf.text[i] != '\0' && j < 12; i++, j++)
{
center_phone[j] = msgbuf.text[i];
}
center_phone[j] = '\0';
printf("center:%s\n",center_phone);
cmd_sms = msgbuf.text[0];
pthread_cond_signal(&cond_sms);
pthread_mutex_unlock(&mutex_sms);
}
break;
default:
break;
}
}
}
#if 0
long msgtype;//��������Ϣ����
��Ϣ���͵ķ��䣺
1L: LED����
2L: ����������
3L: ��·LED��ģ����������
4L: ����
5L: ��ʪ����ֵ����
6L-7L-8L-9L,���ڸ��˵���չ
10L: 3Gͨ��ģ��-GPRS
switch(msgbuf.msgtype){
case 1L: ... break;
....
default .... break;
}
#endif
除了风扇现在都没问题了,风扇这里zigbee程序有问题,不能处理usb串口发送的指令,只能通过zigbbe自组的网络进行控制。