Read USP Chapter 2.
Programs, Processes and Threads
Example (2.2 from USP):
If the CPU starts executing process 1, loses the CPU after 5 instructions, and then executes 4 instructions of process 2 before losing the CPU, the instructions executed might be:
2451, 2461, 2471, 2451, 2461, 102, 112, 122, 132, 2471, 2451, 2461, ...
There are two threads of execution:
2451, 2461, 2471,
2451, 2461, 2471 ... and
102, 112, 122, 132.
The subscript indiates which process is executing and appears only for clarity.
A thread is an abstact data type that represents a
thread of execution of a process.
It is a basic unit of CPU utililization.
A thread has:
Figure 2.1 (page 24): Simple layout of a program image in main memory.
An argument array is an array of pointers terminated by a NULL pointer.
Each element of the array is of type char * and represents a string.
Figure 2.2 (page 32): The argv array for the call mine -c 10 2.0.
Sometimes it is necessary to create a structure like this yourself from a
The shell must do this when you execute a command.
argv is an array of pointers to chars
In C, this is the same as a pointer to a pointer to a char.
One way to write a function to do this is:
char **makeargv(char *s)
If you want to return the number of tokens, you can pass a pointer to the
arg array as in:
int makeargv(char *s, char ***argvp)
The version we will use has an additional parameter that specifies a string
int makeargv(const char *s, const char *delimiters, char ***argvp)
The const for the first two parameters indicates that the strings should not be modified by the function.
Program 2.1 shows a use of this version.
Can use strtok:
char *strtok(char *restrict s1, const char *restrict s2);
s1 is the string to parse
s2 is a string of delimiters
returns a pointer to the next token or NULL if none left.
First call: s1 points to the string to parse
Additional calls: s1 is NULL.
Note: the string s1 is modified.
We do not want the string passed to makeargv to be modified so we allocate space for another copy of the string.
Figure 2.3 (page 36): The makeargv makes a working copy of the string s so that it does not modify that input parameter.
Figure 2.4 (page 36): The use of strtok to allocate strings in place for makeargv.
Program 2.2 shows an implementation of makeargv.
strtok is not safe to use with threads since it remembers the previous state.
Another version is available: strtok_r in which you pass another parameter which is used to remember where it is.
char *strtok_r(char *restrict s1, const char *restrict s2, char **restrict lasts);
You must declare a char pointer to hold the current position and pass a pointer to it as the last argument to strtok_r.
Programs that use strtok can fail even if they do not involve signals or multiple threads.
Suppose you are given the task to write a program that calculates the average
number of words per line in a text file. You write a function:
double wordaverage(char *s);
to do this.
You parse the input string into lines using strtok and call a function
int wordcount(char *s);
to count the words in each line. You assign the task of implementing wordcount to another programmer.
If the other programmer also uses strtok in the implementation of wordcount, your program will fail.
Each of wordcount and wordaverage is correct by itself, but they do not work together correctly.
You can solve this problem by using strtok_r in either function.
Storage classes: static and automatic
Linkage class determines whether variables can be accessed in files other than the one in which they are declared.
|Where Declared||static Modifies||static
|inside a function||storage class||yes||static||none|
|inside a function||storage class||no||automatic||none|
|outside any function||linkage class||yes||static||internal|
|outside any function||linkage class||no||static||external|
Table A.3, page 814 (extended)
Effect of using the static keyword modifier in a C program.