Книга: Programming with POSIX® Threads

6.4.1 flockfile and funlockfile

6.4.1 flockfile and funlockfile

void flockfile (FILE *file);

int ftrylockfile (FILE *file);

void funlockfile (FILE *file);

In some cases, it is important that a sequence of stdio operations occur in uninterrupted sequence; for example, a prompt followed by a read from the terminal, or two writes that need to appear together in the output file even if another thread attempts to write data between the two stdio calls. Therefore, Pthreads adds a mechanism to lock a file and specifies how file locking interacts with internal stdio locking. To write a prompt string to stdin and read a response from stdout without allowing another thread to read from stdin or write to stdout between the two, you would need to lock both stdin and stdout around the two calls as shown in the following program, flock.c. 19-20 This is the important part: Two separate calls to flockfile are made, one for each of the two file streams. To avoid possible deadlock problems within stdio, Pthreads recommends always locking input streams before output streams, when you must lock both. That's good advice, and I've taken it by locking stdin before stdout.

29-30 The two calls to funlockfile must, ofcourse, be made in the opposite order. Despite the specialized call, you are effectively locking mutexes within the stdio library, and you should respect a consistent lock hierarchy.

? flock.c

1 #include <pthread.h>
2 #include "errors.h"

3
4 /*
5 * This routine writes a prompt to stdout (passed as the thread's
6 * "arg"), and reads a response. All other I/O to stdin and stdout
7 * is prevented by the file locks until both prompt and fgets are
8 * complete.
9 */
10 void *prompt_routine (void *arg)
11 {
12 char *prompt = (char*)arg;
13 char *string;
14 int len;

15
16 string = (char*)malloc (128);
17 if (string == NULL)
18  errno_abort ("Alloc string");
19 flockfile (stdin);
20 flockfile (stdout);
21 printf (prompt);
22 if (fgets (string, 128, stdin) == NULL)
23  string[0] = '' ;
24 else {
25  len = strlen (string);
26  if (len > 0 && string[len-l] == 'n')
27  string[len-l] = '';
28  }
29 funlockfile (stdout);
30 funlockfile (stdin);
31 return (void*)string;
32 }

33
34 int main (int argc, char *argv[])
35 {
36 pthread_t threadl, thread2, thread3;
37 char *string;
38 int status;

39
40 #ifdef sun
41 /*
42 * On Solaris 2.5, threads are not timesliced. To ensure
43 * that our threads can run concurrently, we need to
44 * increase the concurrency level.
45 */
46 DPRINTF (("Setting concurrency level to 4n"));
47 thr_setconcurrency (4);
48 #endif
49 status = pthread_create (
50 &threadl, NULL, prompt_routine, "Thread 1> ");
51 if (status != 0)
52  err_abort (status, "Create thread");
53 status = pthread_create (
54  &thread2, NULL, prompt_routine, "Thread 2> ");
55 if (status != 0)
56  err_abort (status, "Create thread");
57 status = pthread_create (
58  &thread3, NULL, prompt_routine, "Thread 3> ");
59 if (status != 0)
60  err_abort (status, "Create thread");
61 status = pthread_join (threadl, (void**)&string);
62 if (status != 0)
63  err_abort (status, "Join thread");
64 printf ("Thread 1: "%s"n", string);
65 free (string);
66 status = pthread_join (thread2, (void**)&string);
67 if (status != 0)
68 err_abort (status, "Join thread");
69 printf ("Thread 1: "% s"n", string);
70 free (string);
71 status = pthread_join (thread3, (void**)&string);
72 if (status != 0)
73 err_abort (status, "Join thread");
74 printf ("Thread 1: "% s"n", string);
75 free (string);
76 return 0;
77 }

You can also use the flockfile and funlockfile functions to ensure that a series of writes is not interrupted by a file access from some other thread. The ftrylockfile function works like pthread_mutex_trylock in that it attempts to lock the file and, if the file is already locked, returns an error status instead of blocking.

Оглавление книги


Генерация: 1.146. Запросов К БД/Cache: 3 / 1
поделиться
Вверх Вниз