I read about APUE 3rd, 8.16 Process Scheduling, there is an example written to verify that changing nice value of a process will affect its priority, I rewrite the code like below:
#include <errno.h> #include <limits.h> #include <stdio.h> #include <stdlib.h> #include <sys/time.h> #include <unistd.h> long long count; struct timeval end; static void check_time(const char* str); int main(int argc, char* argv[]) { pid_t pid; char* s; int nzero, ret; int adj = 0; setbuf(stdout, NULL); #if defined(NZERO) nzero = NZERO; #elif defined(_SC_NZERO) nzero = sysconf(_SC_NZERO); #else #error NZERO undefined #endif printf("NZERO = %dn", nzero); if (argc == 2) adj = strtol(argv[1], NULL, 10); gettimeofday(&end, NULL); end.tv_sec += 10; if ((pid = fork()) < 0) { perror("fork error"); return -1; } else if (pid == 0) { s = "child"; printf("child nice:%d, adjusted by %dn", nice(0) + nzero, adj); errno = 0; if ((ret = nice(adj)) == -1 && errno != 0) { perror("nice error"); return -1; } printf("child now nice:%dn", ret + nzero); } else { s = "parent"; printf("parent nice:%dn", nice(0) + nzero); } while (1) { if (++count == 0) { printf("count overflown"); return -1; } check_time(s); } return 0; } static void check_time(const char* str) { struct timeval tv; gettimeofday(&tv, NULL); if (tv.tv_sec >= end.tv_sec && tv.tv_usec >= end.tv_usec) { printf("%s count:%lldn", str, count); exit(0); } }
And the result of the example is shown below:
NZERO = 20
parent nice:20
child nice:20, adjusted by 0
child now nice:20
parent count:601089419
child count:603271014
Looks like no effect has been made on the child process, why? And how to make the result the way I expect?
(my platform is: Linux liucong-dell 4.4.0-93-generic #116~14.04.1-Ubuntu SMP Mon Aug 14 16:07:05 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux)
Advertisement
Answer
Your multi-core CPU can happily run both the parent and the child simultaneously. As long as both can run, their relative priorities don’t matter.
In order to see the effect of nice
, you have to load your machine such that there’s always a process ready and waiting to run. The easiest way would be making your test multithreaded. Spawn (after the fork
) a few worker threads in both the parend and the child, make them all increment the counter (make it either atomic or thread local), and see what happens.