0
点赞
收藏
分享

微信扫一扫

【Java并发】聊聊并发编程中的锁

RIOChing 2023-09-17 阅读 44

目录

1.项目概述

2.程序框架

3.函数准备

3.1需要函数知识点

3.2编码提醒

4.代码

5.注意事项


1.项目概述

控制端有两个,语音串口UART和Tcp通讯。

执行端有IO输出和IO输入。

2.程序框架

程序分为3部分-------------1.输入控制  2.输出设备  3.主函数-多线程

输入控制的模块----实现指令的收集,并将数据放在一个定义的<cmd.h>头文件种。

输出设备模块----实现设备初始化、设备启动、设备关闭的函数封装放在<device.h>种。

主函数-----实现UART和Tcp两个接收线程,不断接收指令并解析指令调用不同的设备函数封装

亮点,在<.h>封装了一个类,调用<.h>可以编码一个对象,然后用链表将一类对象串起来。

将对象的功能实现都封装成了函数,放在对象的结构体中,使用时直接调用。

3.函数准备

3.1需要函数知识点

main中

  • 线程创建、线程退出、线程等待、wiringPi库、链表增加、链表查找

<cmd.h><device.h>中

  • 链表创建、函数指针

设备控制、输入控制中

  • wiringPi库、结构体赋值、链表增加

3.2编码提醒

出现不能用NULL指针,包含头文件<stdlib.h>

香橙派编译wiringpi库时用gcc  buzzer.c -o test -lwiringPi -lwiringPiDev -lpthread -Im -Icrypt -Irt

C语言函数没有return语句时,会返回最后一次赋值的变量的值

函数指针是定义一个指针指向函数,调用时直接用P()或者(*p)()都行,函数名和函数地址一样

指针有点神奇,指针是一个地址,但是同时也可以直接用指针使用地址里的值

没办法:这里的代码在结构体实现里用了函数的递归。错错错。第575课,添加声音识别模块,形参和实参不一样的。形参只是形式,需要函数调用时赋予实参。

炫技:这里的代码用了链表串联设备

堆栈的存储:在函数体前面的变量,后面的函数可以直接用

Orangepi的引脚图

4.代码

main中

#include <stdio.h>
#include <stdlib.h>
#include "contrldevice.h"
#include "inputcmd.h"
#include <string.h>
#include <wiringPi.h>
#include <pthread.h>
#include<unistd.h>

struct OutputDevice * pdevicehead=NULL; /*device head */
struct InputDevice * pInputhead=NULL; /*Input head */
struct InputDevice * tmp=NULL;

struct OutputDevice *find_cmd_device(char *name,struct OutputDevice * pdevicehead)
{
struct OutputDevice *tmp=pdevicehead;

if(tmp==NULL ){ /* compare is correct*/
return NULL;
}else{
while(tmp!=NULL){
if(0==strcmp(tmp->device_name,name)){
return tmp;
}
tmp=tmp->next;
}
return NULL;
}
}

struct InputDevice *find_input_device(char *name,struct InputDevice * pdevicehead)
{
struct InputDevice *tmp=pdevicehead;

if(tmp==NULL ){ /* compare is correct*/
return NULL;
}else{
while(tmp!=NULL){
if(0==strcmp(tmp->cmddevice_name,name)){
return tmp;
}
tmp=tmp->next;
}
return NULL;
}
}

void * voice_thread(void *data) /* voice_thread */
{
int nread;
struct InputDevice * tmp=find_input_device("voice",pInputhead);
if(tmp==NULL){
printf("no find voice phead!\r\n");
pthread_exit(NULL);

}else{
if(tmp->init(tmp)==-1){
printf("voice init faild!\r\n");
pthread_exit(NULL);
}
}

while(1){
memset(tmp->cmd,0,sizeof(tmp->cmd));
nread=tmp->getcmd(tmp); /* when uart no data come cmd while get uart overtime */
if(nread==0){
printf("voice cmd no data arival!\r\n");
}else{
printf("voice recive %d data:%s\r\n",nread,tmp->cmd);
}
}

}

void * sockread_thread(void *data)
{
int nread;
while(1){
memset(tmp->cmd,'\0',sizeof(tmp->cmd));
nread=read(tmp->ss_fd,&tmp->cmd,sizeof(tmp->cmd));
if(nread==0){ /* cannot recv cmd */
printf("connect is cutdon! \r\n");
pthread_exit(NULL);
}else{ /*can recive cmd */
printf("server receved %d cmd:%s \r\n",nread,tmp->cmd);
}
}

}


void * socket_thread(void *data)
{
int nread;
pthread_t socketreadthread;
tmp=find_input_device("socket",pInputhead);
if(tmp==NULL){
printf("no find socket phead!\r\n");
pthread_exit(NULL);

}else{
if(tmp->init(tmp)==-1){
printf("socket init faild!\r\n");
pthread_exit(NULL);
}
}

while(1){

if(tmp->getcmd(tmp)==-1){
perror("error"); /* get ss_fd error */
}
/*socket read线程*/
pthread_create(&socketreadthread,NULL,sockread_thread,NULL);
pthread_join(socketreadthread,NULL); /* 等读线程退出在进行 */
}
}



int main(void)
{
char device_name[32];

pthread_t voicethread;
pthread_t socketthread;



if(-1==wiringPiSetup()){
printf("wiringpi init fail!\r\n");
return 0;
}
/*1.指令工厂初始化 加入设备 */
pInputhead=add_input_voice(pInputhead);
pInputhead=add_input_socket(pInputhead);

/*2.设备工厂初始化 加入设备 */
pdevicehead=add_device_dingnerlight(pdevicehead);
pdevicehead=add_device_restlight(pdevicehead);
pdevicehead=add_device_firedetect(pdevicehead);

/*2.1找设备 */
/*struct OutputDevice * tmp=find_cmd_device(device_name,pdevicehead);
while(1){
printf("input device name:");
scanf("%s",device_name);
tmp=find_cmd_device(device_name,pdevicehead);
printf("input cmd name 1/2:");
scanf("%d",
switch(cmd){
case 1:
tmp->init();
tmp->open();
break;
case 2:
tmp->init();
tmp->close();
break;
default:
printf("no this cmd");
break;
}
}*/



/*3. 线程池建立*/
/*3.1 语音线程*/
pthread_create(&voicethread,NULL,voice_thread,NULL);

/*3.2socket线程*/
pthread_create(&socketthread,NULL,socket_thread,NULL);



/*3.3摄像头线程*/
/*3.4 火灾线程*/

pthread_join(voicethread,NULL); /*线程等待不让主程序退出*/
pthread_join(socketthread,NULL); /*线程等待不让主程序退出*/
return 0;
}

contrldevice.h

#include <stdio.h>

struct OutputDevice{
char device_name[32];
int status;

int (*init)();
int (*open)();
int (*close)();

int (*read)();
int (*changeStatus)();

struct OutputDevice *next;

};
struct OutputDevice * add_device_dingnerlight(struct OutputDevice *phead);
struct OutputDevice * add_device_restlight(struct OutputDevice *phead);
struct OutputDevice * add_device_firedetect(struct OutputDevice *phead);

inputcmd.h

#include <stdio.h> 


struct InputDevice{

char cmddevice_name[32];
char cmd[32];
int fd;
int ss_fd;

int (*init)();
int (*getcmd)();

struct InputDevice *next;

};

struct InputDevice * add_input_voice(struct InputDevice *phead);
struct InputDevice * add_input_socket(struct InputDevice *phead);

dingnerlight.c

#include <stdio.h> 
#include "contrldevice.h" //include i can use struct
#include <wiringPi.h>

#define dingnerlightPin 2
/*struct OutputDevive{
char device_name[32];
int status;

int (*init)();
int (*open)();
int (*close)();

int (*read)();
int (*changeStatus)();

sturct OutputDevive *next;

} */


int dingnerlight_init(void)
{
pinMode(dingnerlightPin,OUTPUT);
digitalWrite(dingnerlightPin,HIGH);

return 0;

}
int dingnerlight_open(void)
{
digitalWrite(dingnerlightPin,LOW);
return 0;
}

int dingnerlight_close(void)
{
digitalWrite(dingnerlightPin,HIGH);
return 0;
}

struct OutputDevice dingnerlight={ /*"this give valve not init"*/
.device_name="dingnerlight",
.init=dingnerlight_init,
.open=dingnerlight_open,
.close=dingnerlight_close
};

struct OutputDevice * add_device_dingnerlight(struct OutputDevice *phead)
{
if(phead==NULL){
return &dingnerlight;
}else{
dingnerlight.next=phead;
phead=&dingnerlight;
return phead;

}
}

firedetect.c

#include <stdio.h> 
#include "contrldevice.h" //include i can use struct
#include <wiringPi.h>

#define firedetectPin 6
/*struct OutputDevice{
char device_name[32];
int status;

int (*init)();
int (*open)();
int (*close)();

int (*read)();
int (*changeStatus)();

sturct OutputDevive *next;

} */


int firedetect_init(void)
{
pinMode(firedetectPin,INPUT);


return 0;
}

int firedetect_read(void)
{
return digitalRead(firedetectPin);
}


struct OutputDevice firedetect={ /*"this give valve not init"*/
.device_name="firedetect",
.init=firedetect_init,
.read=firedetect_read
};

struct OutputDevice * add_device_firedetect(struct OutputDevice *phead)
{
if(phead==NULL){
return
}else{
firedetect.next=phead;
phead=
return phead;

}
}

restlight.c

#include <stdio.h> 
#include "contrldevice.h" //include i can use struct
#include <wiringPi.h>

#define restlightPin 8
/*struct OutputDevice{
char device_name[32];
int status;

int (*init)();
int (*open)();
int (*close)();

int (*read)();
int (*changeStatus)();

sturct OutputDevice *next;

} */


int restlight_init(void)
{
pinMode(restlightPin,OUTPUT);
digitalWrite(restlightPin,HIGH);

return 0;

}
int restlight_open(void)
{
digitalWrite(restlightPin,LOW);
return 0;
}

int restlight_close(void)
{
digitalWrite(restlightPin,HIGH);
return 0;
}

struct OutputDevice restlight={ /*"this give valve not init"*/
.device_name="restlight",
.init=restlight_init,
.open=restlight_open,
.close=restlight_close
};

struct OutputDevice * add_device_restlight(struct OutputDevice *phead)
{
if(phead==NULL){
return
}else{
restlight.next=phead;
return
}
}

socketcmd.c

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <ctype.h>
#include <arpa/inet.h>
#include "inputcmd.h"/*include i can use struct*/

/*struct InputDevice{

char cmddevice_name[32];
char cmd[32];
int fd;
int ss_fd;

int (*init)();
int (*getcmd)();

struct InputDevice *next;

}; */


int socket_getcmd(struct InputDevice *phead)
{
int len;

struct sockaddr_in c_ddr; /*save clinet msg*/

/*4.accept come and connect for once*/
len=sizeof(c_ddr);


phead->ss_fd=accept(phead->fd,(struct sockaddr *)&c_ddr,
if(phead->ss_fd == -1){
perror("accept:");
}
/*5.read from connect ss_fd*/
/*5.2 read*/


printf("conect succese!==========\r\n");



return phead->ss_fd;
}

int socket_init(struct InputDevice *phead)
{

int s_fd;

struct sockaddr_in s_ddr; /*build server msg*/

s_fd= socket(AF_INET, SOCK_STREAM, 0);/*1.build a soket specified*/
if(s_fd==-1){
perror("error is");
}
/*2.build all bind*/
s_ddr.sin_family=AF_INET;
s_ddr.sin_port=htons(8880);
s_ddr.sin_addr.s_addr=htonl(INADDR_ANY);
/*give the bind*/
bind(s_fd,(struct sockaddr *)&s_ddr,sizeof(s_ddr));
/*3.waite for client*/
listen(s_fd,8);

phead->fd=s_fd;

return s_fd;
}

struct InputDevice struc_socket={
.cmd={0},
.cmddevice_name="socket",
.init=socket_init,
.getcmd=socket_getcmd

};

struct InputDevice * add_input_socket(struct InputDevice *phead)
{
if(phead==NULL){
return &struc_socket;
}else{
struc_socket.next=phead;
phead=&struc_socket;
return phead;
}
}

voicecmd.c

  //include i can use struct
#include <wiringPi.h>
#include <wiringSerial.h>
#include <stdlib.h>
#include <unistd.h>
#include "inputcmd.h"

/*struct InputDevice{

char cmddevice_name[32];
char cmd[32];
int fd;

int (*init)();
int (*getcmd)();

sturct InputDevice *next;

} */


int voice_getcmd(struct InputDevice *phead)
{
int nread;
nread=read(phead->fd,phead->cmd,sizeof(phead->cmd));

return nread;


}

int voice_init(struct InputDevice *phead)
{
int fd1;
if((fd1=serialOpen("/dev/ttyS5",115200))<0){
printf("uart init fail!\r\n");
exit(-1);
}
phead->fd=fd1;
return fd1;
}

struct InputDevice voice={
.cmd={0},
.cmddevice_name="voice",
.init=voice_init,
.getcmd=voice_getcmd

};

struct InputDevice * add_input_voice(struct InputDevice *phead)
{
if(phead==NULL){
return
}else{
voice.next=phead;
phead=
return phead;
}
}

5.注意事项

举报

相关推荐

0 条评论