pthread_getcpuclockid() function in C
In this article, we will discuss the pthread_getcpuclockid() function in C with its syntax and examples.
What is pthread_getcpuclockid() function?
The C function pthread_getcpuclockid() is a POSIX thread (pthread) library function that is used to obtain the clock ID linked to a specific thread. This feature is a component of the POSIX threads API, an open interface for multithreading in Unix-like operating systems.
Syntax:
It has the following syntax:
int pthread_getcpuclockid (pthread_t id, clockid_t* clock_id);
Parametres:
- thread: It is the thread ID for which we want to obtain the clock ID. It can be obtained by using the pthread_create() or pthread_self() functions.
- clock_id: It is a reference to an object called clockid_t, in which the function can store the clock ID.
Return value: The CPU clock time for a particular thread is returned by this method.
- The function returns 0 upon success.
- It returns an error code if it doesn't work.
Purpose:
pthread_getcpuclockid()'s primary goal is to retrieve the clock ID linked to a particular thread's CPU-time clock. The CPU-time clock tracks the duration of a thread’s CPU execution.
Example:
Let us take an example to illustrate the use of the pthread_getcpuclockid() in C:
#include <errno.h>
#include <pthread.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#define handle_error(msg) \
do
{ \
perror(msg); \
exit(EXIT_FAILURE); \
} while (0)
#define handle_error_en(en, msg) \
do
{ \
errno = en; \
perror(msg); \
exit(EXIT_FAILURE); \
} while (0)
static void* thread_start(void* arg)
{
printf("Custom Subthread starting infinite loop\n");
for (;;)
continue;
}
static void pclock(char* msg, clockid_t cid)
{
struct timespec ts;
printf("%s", msg);
if (clock_gettime(cid, &ts) == -1)
handle_error("clock_gettime");
printf("%4jd.%03ld\n", (intmax_t)ts.tv_sec, ts.tv_nsec / 1000000);
}
int main(int argc, char* argv[])
{
pthread_t thread;
clockid_t cid;
int s;
s = pthread_create(&thread, NULL, thread_start, NULL);
if (s != 0)
handle_error_en(s, "pthread_create");
printf("Modified Main thread sleeping\n");
sleep(2); // Modified sleep duration
printf("Modified Main thread consuming some CPU time...\n");
for (int j = 0; j < 3000000; j++) // Modified CPU time consuming loop
getppid();
pclock("Modified Process total CPU time: ", CLOCK_PROCESS_CPUTIME_ID);
s = pthread_getcpuclockid(pthread_self(), &cid);
if (s != 0)
handle_error_en(s, "pthread_getcpuclockid");
pclock("Modified Main thread CPU time: ", cid);
s = pthread_getcpuclockid(thread, &cid);
if (s != 0)
handle_error_en(s, "pthread_getcpuclockid");
pclock("Modified Subthread CPU time: ", cid);
// Modified sleep duration before terminating
printf("Modified Main thread sleeping before termination\n");
sleep(2);
// Terminates both threads
exit(EXIT_SUCCESS);
}
Output:
Custom Subthread starting infinite loop
Main thread sleeping
Modified Main thread sleeping
Main thread consuming some CPU time...
Modified Main thread consuming some CPU time...
Process total CPU time: 0.001
Modified Process total CPU time: 0.003
Main thread CPU time: 0.000
Modified Main thread CPU time: 0.001
Modified Subthread CPU time: 1 0.000
Modified Main thread sleeping before termination
Example 2:
Let us take another example to illustrate the use of the pthread_getcpuclockid() in C:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <time.h>
#include <unistd.h>
#define handle_error(msg) \
do { \
perror(msg); \
exit(EXIT_FAILURE); \
} while (0)
static void* thread_function(void* arg) {
// Get the clock ID associated with the CPU-time clock for this thread
clockid_t clock_id;
if (pthread_getcpuclockid(pthread_self(), &clock_id) != 0) {
perror("pthread_getcpuclockid");
exit(EXIT_FAILURE);
}
// Simulate some CPU-bound work
for (int i = 0; i < 5000000; ++i) {
// Do some work
}
// Print the CPU time consumed by the thread
struct timespec ts;
if (clock_gettime(clock_id, &ts) != 0) {
perror("clock_gettime");
exit(EXIT_FAILURE);
}
printf("Thread CPU time: %ld seconds %ld nanoseconds\n", ts.tv_sec, ts.tv_nsec);
return NULL;
}
int main() {
pthread_t thread1, thread2;
// Create two threads
if (pthread_create(&thread1, NULL, thread_function, NULL) != 0 ||
pthread_create(&thread2, NULL, thread_function, NULL) != 0) {
handle_error("pthread_create");
}
// Wait for both threads to finish
if (pthread_join(thread1, NULL) != 0 || pthread_join(thread2, NULL) != 0) {
handle_error("pthread_join");
}
return 0;
}
Output:
Thread CPU time: 0 seconds 150000000 nanoseconds
Thread CPU time: 0 seconds 150000000 nanoseconds
Conclusion:
The C function pthread_getcpuclockid() function is important to determine the clock ID linked to the CPU-time clock for a particular thread, which is a component of the POSIX Threads library. It is very useful when the exact measurement of the CPU time spent by individual threads is needed. Developers may use the clock_gettime() function to obtain precise timestamps prior to and following particular thread operations, allowing the computation of the exact CPU time spent. This function retrieves the CPU clock ID. This feature is useful for performance analysis, profiling, and optimizing multithreaded apps because it offers information on how each thread uses its resources. It's important to remember that the architecture of the underlying system and the scheduler behaviour may have an impact on how effective this function is, so it's important to interpret the results carefully in accordance with the particular application and system characteristics.