23789|0

156

帖子

1

TA的资源

一粒金砂(中级)

楼主
 

【树莓派3B+测评】线程的挂起与恢复&CPU温度检测 [复制链接]

本帖最后由 donatello1996 于 2018-12-22 17:33 编辑

    在TCP通信中,除了线程的创建和删除以外,挂起和解挂也是非常重要的步骤,简单而言,挂起线程就是让该线程暂停执行,一直在阻塞,而解挂线程(恢复)就顾名思义了,解除挂起状态继续运行,这里我再开辟一个线程用于循环检测CPU温度,一秒检测一次,以确保系统在正常运作。读取温度的方法是读取/sys/class/thermal/thermal_zone0/temp文件的数值,将数值传输到标准文件流,再通过printf终端输出:


#define TEMP_PATH "/sys/class/thermal/thermal_zone0/temp"
int fd;
char buf[30];
fd = open(TEMP_PATH, O_RDONLY);
read(fd, buf, 30);


然后是线程的创建,除了之前的创建线程本身以外,还要创建互斥锁和cond:
pthread_create(&id2,NULL,Thread_CPU_Temp,NULL);
                printf("CPU温度检测线程建立\n");
                if (pthread_mutex_init(&mut,NULL))
                {
                        printf("互斥锁初始化失败\n");
                }
                if (pthread_cond_init(&cond,NULL))
                {
                        printf("cond初始化失败\n");
                }


挂起和解挂其实就是对锁和cond信号量的操作:
void thread_resume()
{
        if (status == STOP)
        {
                pthread_mutex_lock(&mut);
                status = RUN;
                pthread_cond_signal(&cond);
                printf("CPU温度检测线程恢复运行\n");
                pthread_mutex_unlock(&mut);
        }
        else
        {
                printf("CPU温度检测线程一直在运行\n");
        }
}


void thread_pause()
{
        if (status == RUN)
        {
                pthread_mutex_lock(&mut);
                status = STOP;
                printf("CPU温度检测线程暂停(挂起)\n");
                pthread_mutex_unlock(&mut);
        }
        else
        {
                printf("CPU温度检测线程一直在暂停\n");
        }
}


操作cond信号量的时候必须锁上线程的共享资源,如果该线程挂起了,那么这个线程就一直阻塞而不执行任何操作,Linux系统在轮转执行到此线程


时间片的时候会自动跳过此线程。


完整代码如下:


#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "raspi_led_pwm.h"


int fd_socket;
pthread_t id1,id2;


#define RUN  1
#define STOP 0


pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
unsigned char sendbuf[100],recvbuf[100];
int thread_flag=0,status=STOP;


#define TEMP_PATH "/sys/class/thermal/thermal_zone0/temp"


void *Thread_CPU_Temp(void *arg)
{
    int fd;
    double temp = 0;
    char buf[30];
    while(1)
    {
        pthread_mutex_lock(&mut);
        while(!status)
        {
            pthread_cond_wait(&cond, &mut);
        }
        pthread_mutex_unlock(&mut);
        fd = open(TEMP_PATH, O_RDONLY);
        if (fd < 0)
        {
            fprintf(stderr, "无法打开thermal_zone0/temp文件\n");
            return -1;
        }


        if (read(fd, buf, 30) < 0)
        {
            fprintf(stderr, "读取温度数据失败\n");
            return -1;
        }


        temp = atoi(buf) / 1000.0;
        printf("%.2f\n", temp);


        sleep(1);
    }
}


void thread_resume()
{
        if (status == STOP)
        {
                pthread_mutex_lock(&mut);
                status = RUN;
                pthread_cond_signal(&cond);
                printf("CPU温度检测线程恢复运行\n");
                pthread_mutex_unlock(&mut);
        }
        else
        {
                printf("CPU温度检测线程一直在运行\n");
        }
}


void thread_pause()
{
        if (status == RUN)
        {
                pthread_mutex_lock(&mut);
                status = STOP;
                printf("CPU温度检测线程暂停(挂起)\n");
                pthread_mutex_unlock(&mut);
        }
        else
        {
                printf("CPU温度检测线程一直在暂停\n");
        }
}


void *Thread_Send_buf(void *arg)
{
    int len;
    while(1)
    {
        bzero(sendbuf,100);
        scanf("%s",sendbuf);
        if(sendbuf[0]=='1')
        {
            if(thread_flag==0)
            {
                thread_flag=1;
                pthread_create(&id2,NULL,Thread_CPU_Temp,NULL);
                printf("CPU温度检测线程建立并处于阻塞状态\n");
                if (pthread_mutex_init(&mut,NULL))
                {
                        printf("互斥锁初始化失败\n");
                }
                if (pthread_cond_init(&cond,NULL))
                {
                        printf("cond初始化失败\n");
                }
            }
        }
        else if(sendbuf[0]=='2')
        {
            thread_pause();
        }
        else if(sendbuf[0]=='3')
        {
            thread_resume();
        }
        for(len=0;sendbuf[len]!='\0';len++);
        send(fd_socket,sendbuf,len,0);
    }
}


int main()
{
        int i=0;
        int ret=-1;
        wiringPiSetup();
        //Raspi_LED_Init();
        //Raspi_PWM_Init(100);
        //pwmWrite(1,60);


        /*
        struct sockaddr_in sockaddr_in_comm,sockaddr_in_settings;
        bzero(&sockaddr_in_settings,sizeof(sockaddr_in_settings));
        sockaddr_in_settings.sin_family=AF_INET;
        sockaddr_in_settings.sin_addr.s_addr=inet_addr("169.254.122.5");
        sockaddr_in_settings.sin_port=htons(8087);
        */


        socklen_t addrsize=sizeof(struct sockaddr);
        struct sockaddr_in girladdr;
        bzero(&girladdr,sizeof(girladdr)); // 清零
        girladdr.sin_family=AF_INET;
        girladdr.sin_port=htons(10086);
        girladdr.sin_addr.s_addr=inet_addr("169.254.122.1");


        int thread_1=0;
        while(1)
        {
            while(1)
            {
                fd_socket=socket(AF_INET,SOCK_STREAM,0);
                if(fd_socket==-1)
                {
                        printf("套接字初始化失败!\n");
                        return -1;
                }
                ret=connect(fd_socket,(struct sockaddr *)&girladdr,addrsize);
                if(ret==0)
                {
                    printf("与服务器建立连接\n");
                    ret=pthread_create(&id1,NULL,Thread_Send_buf,NULL);
                    if(ret==0)
                        printf("TCP发送阻塞线程被创建\n");
                    break;
                }
            }
            while(1)
            {
                bzero(recvbuf,100);
                ret=recv(fd_socket,recvbuf,100,0);
                if(ret==0)
                {
                    printf("与服务器失去连接\n");
                    ret=pthread_cancel(id1);
                    if(ret==0)
                        printf("TCP发送阻塞线程被取消\n");
                    break;
                }
                printf("服务器端发来信息:%s\n",recvbuf);
            }
        }


}

看看效果,当输入1的时候,创建CPU温度检测线程,输入2的时候,线程挂起,输入3的时候线程恢复运行:

点赞 关注(1)

回复
举报
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/7 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表