2.7 Thread-Safe Functions

Team-FLY

The strtok function is not a model that you should emulate in your programs. Because of its definition (page 35), it must use an internal static variable to keep track of the current location of the next token to parse within the string. However, when calls to strtok with different parse strings occur in the same program, the parsing of the respective strings may interfere because there is only one variable for the location.

Program 2.3 shows an incorrect way to determine the average number of words per line by using strtok . The wordaverage function determines the average number of words per line by using strtok to find the next line. The function then calls wordcount to count the number of words on this line. Unfortunately, wordcount also uses strtok , this time to parse the words on the line. Each of these functions by itself would be correct if the other one did not call strtok . The wordaverage function works correctly for the first line, but when wordaverage calls strtok to parse the second line, the internal state information kept by strtok has been reset by wordcount .

The behavior that causes wordaverage to fail also prevents strtok from being used safely in programs with multiple threads. If one thread is in the process of using strtok and a second thread calls strtok , subsequent calls may not behave properly. POSIX defines a thread-safe function, strtok_r , to be used in place of strtok . The _r stands for reentrant , an obsolescent term indicating the function can be reentered (called again) before a previous call finishes.

Program 2.3 wordaveragebad.c

An incorrect use of strtok to determine the average number of words per line .

 #include <string.h> #define LINE_DELIMITERS "\n" #define WORD_DELIMITERS " " static int wordcount(char *s) {    int count = 1;    if (strtok(s, WORD_DELIMITERS) == NULL)       return 0;    while (strtok(NULL, WORD_DELIMITERS) != NULL)       count++;    return count; } double wordaverage(char *s) {      /* return average size of words in s */    int linecount = 1;    char *nextline;    int words;    nextline = strtok(s, LINE_DELIMITERS);    if (nextline == NULL)       return 0.0;    words = wordcount(nextline);    while ((nextline = strtok(NULL, LINE_DELIMITERS)) != NULL) {       words += wordcount(nextline);       linecount++;    }    return (double)words/linecount; } 

The strtok_r function behaves similarly to strtok except for an additional parameter, lasts , a user -provided pointer to a location that strtok_r uses to store the starting address for the next parse.

  SYNOPSIS  #include <string.h>    char *strtok_r(char *restrict s, const char *restrict sep,                   char **restrict lasts);  POSIX:TSF  

Each successive call to strtok_r returns the start of the next token and inserts a '\0' at the end of the token being returned. The strtok_r function returns NULL when it reaches the end of s .

Program 2.4 corrects Program 2.3 by using strtok_r . Notice that the identifier lasts used by each function has no linkage, so each invocation accesses a distinct object. Thus, the two functions use different variables for the third parameter of strtok_r and do not interfere.

Program 2.4 wordaverage.c

A correct use of strtok_r to determine the average number of words per line .

 #include <string.h> #define LINE_DELIMITERS "\n" #define WORD_DELIMITERS " " static int wordcount(char *s) {    int count = 1;    char *lasts;    if (strtok_r(s, WORD_DELIMITERS, &lasts) == NULL)       return 0;    while (strtok_r(NULL, WORD_DELIMITERS, &lasts) != NULL)       count++;    return count; } double wordaverage(char *s) {     /* return average size of words in s */    char *lasts;    int linecount = 1;    char *nextline;    int words;    nextline = strtok_r(s, LINE_DELIMITERS, &lasts);    if (nextline == NULL)       return 0.0;    words = wordcount(nextline);    while ((nextline = strtok_r(NULL, LINE_DELIMITERS, &lasts)) != NULL) {       words += wordcount(nextline);       linecount++;    }    return (double)words/linecount; } 
Team-FLY


Unix Systems Programming
UNIX Systems Programming: Communication, Concurrency and Threads
ISBN: 0130424110
EAN: 2147483647
Year: 2003
Pages: 274

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net