initial import
from http://www.informit.com/store/programming-with-posix-threads-9780201633924
This commit is contained in:
96
putchar.c
Normal file
96
putchar.c
Normal file
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* putchar.c
|
||||
*
|
||||
* Demonstrate use of stdio file locking to generate an "atomic"
|
||||
* sequence of character writes (using putchar). If run with an
|
||||
* argument of "1", or no argument, the program uses a sequence
|
||||
* of putchar_unlocked calls within flockfile/funlockfile to
|
||||
* ensure that one threads writes cannot be interleaved with
|
||||
* another's.
|
||||
*
|
||||
* With an argument of "0", the program uses putchar, without
|
||||
* file locks, to show that the writes may be interleaved.
|
||||
*
|
||||
* The putchar[_unlocked] loop is punctuated with sleep(1) calls
|
||||
* to ensure that the desired behavior is demonstrated. Without
|
||||
* some delay, even on a multiprocessor the program may often
|
||||
* fail to display the interleaved output in this simplified
|
||||
* case.
|
||||
*
|
||||
* With file locking, you can expect to see the following output:
|
||||
*
|
||||
* thread 1
|
||||
* thread 2
|
||||
* thread 3
|
||||
*
|
||||
* While without file locking, you can expect to see something
|
||||
* much less predictable, but probably resembling this:
|
||||
*
|
||||
* ttthhhiiisss iiisss ttthhhrrreeeaaaddd 123
|
||||
*
|
||||
*/
|
||||
#include <pthread.h>
|
||||
#include "errors.h"
|
||||
|
||||
/*
|
||||
* This function writes a string (the function's arg) to stdout,
|
||||
* by locking the file stream and using putchar_unlocked to
|
||||
* write each character individually.
|
||||
*/
|
||||
void *lock_routine (void *arg)
|
||||
{
|
||||
char *pointer;
|
||||
|
||||
flockfile (stdout);
|
||||
for (pointer = arg; *pointer != '\0'; pointer++) {
|
||||
putchar_unlocked (*pointer);
|
||||
sleep (1);
|
||||
}
|
||||
funlockfile (stdout);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function writes a string (the function's arg) to stdout,
|
||||
* by using putchar to write each character individually.
|
||||
* Although the internal locking of putchar prevents file stream
|
||||
* corruption, the writes of various threads may be interleaved.
|
||||
*/
|
||||
void *unlock_routine (void *arg)
|
||||
{
|
||||
char *pointer;
|
||||
|
||||
for (pointer = arg; *pointer != '\0'; pointer++) {
|
||||
putchar (*pointer);
|
||||
sleep (1);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
pthread_t thread1, thread2, thread3;
|
||||
int flock_flag = 1;
|
||||
void *(*thread_func)(void *);
|
||||
int status;
|
||||
|
||||
if (argc > 1)
|
||||
flock_flag = atoi (argv[1]);
|
||||
if (flock_flag)
|
||||
thread_func = lock_routine;
|
||||
else
|
||||
thread_func = unlock_routine;
|
||||
status = pthread_create (
|
||||
&thread1, NULL, thread_func, "this is thread 1\n");
|
||||
if (status != 0)
|
||||
err_abort (status, "Create thread");
|
||||
status = pthread_create (
|
||||
&thread2, NULL, thread_func, "this is thread 2\n");
|
||||
if (status != 0)
|
||||
err_abort (status, "Create thread");
|
||||
status = pthread_create (
|
||||
&thread3, NULL, thread_func, "this is thread 3\n");
|
||||
if (status != 0)
|
||||
err_abort (status, "Create thread");
|
||||
pthread_exit (NULL);
|
||||
}
|
||||
Reference in New Issue
Block a user