1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | /* * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ /******************************************************************** * Description: CPU and GPU temperature display. * Author: jason,,, <> * Created at: Fri Dec 9 08:53:25 AEDT 2022 * Computer: jason-Lenovo-H50-55 * System: Linux 5.4.0-135-generic on x86_64 * * Copyright (c) 2022 jason,,, All rights reserved. * ********************************************************************/ #include <stdio.h> #include <stdlib.h> int main(int argc, char *argv[]) { /* * Get the CPU temperature */ FILE *fp = popen("cat /sys/class/thermal/thermal_zone0/temp", "r"); if (fp == NULL) { printf("Failed to get CPU temperature\n"); return 1; } int cpu_temp; fscanf(fp, "%d", &cpu_temp); /* Printing the CPU temp divided by 1000. */ printf("CPU temperature: %d C\n", cpu_temp / 1000); pclose(fp); /* * * Getting the GPU temperature. * */ fp = popen("nvidia-smi --query-gpu=temperature.gpu --format=csv,noheader,nounits", "r"); if (fp == NULL) { printf("Failed to get GPU temperature\n"); return 1; } int gpu_temp; fscanf(fp, "%d", &gpu_temp); /* Printing the GPU temperature. */ printf("GPU temperature: %d C\n", gpu_temp); pclose(fp); return 0; } |
Compile the program like this.
(base) jason@jason-Lenovo-H50-55:~$ gcc temp.c -Werror -o cputemp |
And this is the output you will get.
(base) jason@jason-Lenovo-H50-55:~$ ./cputemp CPU temperature: 29 C GPU temperature: 42 C |
This is a simple program, but it works perfectly, without any complicated system calls, you can still retrieve the needed information.
Therefore, to get the CPU temperature, you may also use this one-liner.
(base) jason@jason-Lenovo-H50-55:~$ cat /sys/class/thermal/thermal_zone0/temp | awk '{sum=$1 / 1000} END {print sum}' 31 |
And to get the GPU temperature.
(base) jason@jason-Lenovo-H50-55:~$ nvidia-smi --query-gpu=temperature.gpu --format=csv,noheader,nounits 42 |
Compare it with the code below that gets the kernel version of a Linux machine and the node name.
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 | if (argc > 1 and strncmp(argv[1], "1", BUF) == 0) { /* * The utsname function: */ uname(&uname_pointer); if (strlen (uname_pointer.domainname) < 7 or strncmp(uname_pointer.domainname, "(none)", 10) == 0) { printf ("System name : %s \n" \ "Nodename : %s \n" \ "Release : %s \n" \ "Version : %s \n" \ "Machine : %s \n\n", uname_pointer.sysname, uname_pointer.nodename, uname_pointer.release, uname_pointer.version, uname_pointer.machine ); } else { printf ("System name : %s \n" \ "Nodename : %s \n" \ "Release : %s \n" \ "Version : %s \n" \ "Machine : %s \n" \ "Domain Name : %s \n\n", uname_pointer.sysname, uname_pointer.nodename, uname_pointer.release, uname_pointer.version, uname_pointer.machine, uname_pointer.domainname ); } } |
That is far more complicated but fast.
And this code that prints information from a file is a high-speed function indeed.
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 | void kernel(char,int); /* * @brief /proc file opener * @param File An output stream. * @param len A string length. * @return none. * @pre @a len must be a non-NULL int. * I hope this little function is not offending anyone. it is the only * way I could think to have a single function that would be able to * load the different files quickly and without fuss. And it works just * fine, and that is what matters in the end. */ struct _kern1 { char *File; int len; char Kyo[40]; } *kern1 = (struct _kern1 *) 0x80; void kernel(const char *File, int len) { FILE *f; char Kyo[40]; if (len > 10 or len < 2) return; f = fopen(File, "r"); if(!f) { printf ("Sorry, I cannot open: %s.\n", File); printf("Please check your permissions with\n" \ "your supervisor. The feature may not\n" \ "be compiled and\\or enabled in your\n" \ "kernel version. Or a scsi device, eg,\n" \ "a USB drive may not be attached.\n"); return; } else { /* Based on sample code from: * www.koders.com/c/fid84CFEFBF311605F963CB04E0F84A2F52A8120F33.aspx * Specifically the section on parsing the /proc/version. */ while (feof(f) != 1) { fgets(Kyo, len, f); /* * This function is fast, owing to this i feel. especially with gcc * 4.3.2 & glibc 2.5+. it is faster than using: printf (Kyo); */ fprintf (stdout, "%s", Kyo); fflush(stdout); } } fclose(f); } #endif /* sysinfo.h */ |