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

donatello1996   2018-12-22 17:31 楼主
在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的时候线程恢复运行: 42.jpg 43.jpg 44.jpg 45.jpg 46.jpg 本帖最后由 donatello1996 于 2018-12-22 17:33 编辑

回复评论

暂无评论,赶紧抢沙发吧
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复