Posted: . At: 9:20 AM. This was 1 year ago. Post ID: 17234
Page permalink. WordPress uses cookies, or tiny pieces of information stored on your computer, to verify who you are. There are cookies for logged in users and for commenters.
These cookies expire two weeks after they are set.


A very useful program to get the temperatures of the CPU and GPU on Linux.


temperatures.c
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.

sysinfo.cpp
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.

sysinfo.h
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 */

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.