#ifndef __errors_h
#define __errors_h
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*
* Define a macro that can be used for diagnostic output from
* examples. When compiled -DDEBUG, it results in calling printf
* with the specified argument list. When DEBUG is not defined, it
* expands to nothing.
*/
#ifdef DEBUG
# define DPRINTF(arg) printf arg
#else
# define DPRINTF(arg)
#endif
/*
* NOTE: the "do {" ... "} while (0);" bracketing around the macros
* allows the err_abort and errno_abort macros to be used as if they
* were function calls, even in contexts where a trailing ";" would
* generate a null statement. For example,
*
* if (status != 0)
* err_abort (status, "message");
* else
* return status;
*
* will not compile if err_abort is a macro ending with "}", because
* C does not expect a ";" to follow the "}". Because C does expect
* a ";" following the ")" in the do...while construct, err_abort and
* errno_abort can be used as if they were function calls.
*/
#define err_abort(code,text) do { \
fprintf (stderr, "%s at \"%s\":%d: %s\n", \
text, __FILE__, __LINE__, strerror (code)); \
abort (); \
} while (0)
#define errno_abort(text) do { \
fprintf (stderr, "%s at \"%s\":%d: %s\n", \
text, __FILE__, __LINE__, strerror (errno)); \
abort (); \
} while (0)
#endif
/*
* alarm_thread.c
*
* This version of alarm.c uses pthread_create to create a
* separate thread to wait for each alarm to expire.
*/
#include <pthread.h>
#include "errors.h"
typedef struct alarm_tag {
int seconds;
char message[64];
} alarm_t;
void *alarm_thread (void *arg)
{
alarm_t *alarm = (alarm_t*)arg;
int status;
status = pthread_detach (pthread_self ());
if (status != 0)
err_abort (status, "Detach thread");
sleep (alarm->seconds);
printf ("(%d) %s\n", alarm->seconds, alarm->message);
free (alarm);
return NULL;
}
int main (int argc, char *argv[])
{
int status;
char line[128];
alarm_t *alarm;
pthread_t thread;
while (1) {
printf ("Alarm> ");
if (fgets (line, sizeof (line), stdin) == NULL) exit (0);
if (strlen (line) <= 1) continue;
alarm = (alarm_t*)malloc (sizeof (alarm_t));
if (alarm == NULL)
errno_abort ("Allocate alarm");
/*
* Parse input line into seconds (%d) and a message
* (%64[^\n]), consisting of up to 64 characters
* separated from the seconds by whitespace.
*/
if (sscanf (line, "%d %64[^\n]",
&alarm->seconds, alarm->message) < 2) {
fprintf (stderr, "Bad command\n");
free (alarm);
} else {
status = pthread_create (
&thread, NULL, alarm_thread, alarm);
if (status != 0)
err_abort (status, "Create alarm thread");
}
}
}
gcc alarm_thread.c -lpthread
gcc -pthread pthread_sample.c
댓글 없음:
댓글 쓰기