Add ch01 C++ threading equivalents
This commit is contained in:
5
Makefile
5
Makefile
@@ -67,6 +67,9 @@ NAMES_C=$(SOURCES_C:.c=)
|
||||
PROGRAMS_C=$(addprefix $(BIN)/, $(NAMES_C))
|
||||
|
||||
SOURCES_CXX=\
|
||||
ch01/alarm_cpp.cpp \
|
||||
ch01/alarm_fork_cpp.cpp \
|
||||
ch01/alarm_thread_cpp.cpp \
|
||||
ch03/alarm_mutex_cpp.cpp \
|
||||
ch04/pipe_cpp.cpp
|
||||
|
||||
@@ -77,7 +80,7 @@ all: format dirs ${PROGRAMS_C} ${PROGRAMS_CXX}
|
||||
|
||||
format:
|
||||
#clang-format -i $(SOURCE)/*.c*
|
||||
#clang-format -i $(SOURCE)/*.h*
|
||||
clang-format -i $(SOURCE)/*.h*
|
||||
clang-format -i $(SOURCE)/*/*.c*
|
||||
clang-format -i $(SOURCE)/*/*.h*
|
||||
|
||||
|
||||
38
src/ch01/alarm_cpp.cpp
Normal file
38
src/ch01/alarm_cpp.cpp
Normal file
@@ -0,0 +1,38 @@
|
||||
|
||||
#include <chrono>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
{
|
||||
std::string line;
|
||||
std::string message;
|
||||
|
||||
while (true) {
|
||||
std::cout << "Alarm> ";
|
||||
|
||||
std::getline(std::cin, line);
|
||||
if (!std::cin.good())
|
||||
exit(0);
|
||||
|
||||
if (line.empty())
|
||||
continue;
|
||||
|
||||
std::istringstream in(line);
|
||||
|
||||
unsigned seconds = -1;
|
||||
in >> seconds;
|
||||
message = in.str();
|
||||
|
||||
if (seconds < 1 || message.empty()) {
|
||||
std::cout << "Bad command\n";
|
||||
continue;
|
||||
}
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::seconds(seconds));
|
||||
std::cout << message << "\n";
|
||||
}
|
||||
}
|
||||
57
src/ch01/alarm_fork_cpp.cpp
Normal file
57
src/ch01/alarm_fork_cpp.cpp
Normal file
@@ -0,0 +1,57 @@
|
||||
|
||||
#include "errors.hpp"
|
||||
|
||||
#include <chrono>
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <wait.h>
|
||||
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
{
|
||||
std::string line;
|
||||
std::string message;
|
||||
|
||||
while (true) {
|
||||
std::cout << "Alarm> ";
|
||||
|
||||
std::getline(std::cin, line);
|
||||
if (!std::cin.good())
|
||||
exit(0);
|
||||
|
||||
if (line.empty())
|
||||
continue;
|
||||
|
||||
std::istringstream in(line);
|
||||
|
||||
unsigned seconds = -1;
|
||||
in >> seconds;
|
||||
message = in.str();
|
||||
|
||||
if (seconds < 1 || message.empty()) {
|
||||
std::cout << "Bad command\n";
|
||||
continue;
|
||||
}
|
||||
|
||||
pid_t pid = fork();
|
||||
if (pid == (pid_t) -1)
|
||||
errno_abort("Fork");
|
||||
if (pid == (pid_t) 0) {
|
||||
std::this_thread::sleep_for(std::chrono::seconds(seconds));
|
||||
std::cout << message << "\n";
|
||||
std::exit(0);
|
||||
}
|
||||
|
||||
do {
|
||||
pid = waitpid((pid_t) -1, NULL, WNOHANG);
|
||||
if (pid == (pid_t) -1)
|
||||
errno_abort("Wait for child");
|
||||
} while (pid != (pid_t) 0);
|
||||
}
|
||||
}
|
||||
@@ -26,6 +26,7 @@ alarm_thread(void* arg)
|
||||
free(alarm);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
{
|
||||
|
||||
52
src/ch01/alarm_thread_cpp.cpp
Normal file
52
src/ch01/alarm_thread_cpp.cpp
Normal file
@@ -0,0 +1,52 @@
|
||||
|
||||
#include <chrono>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
|
||||
struct Alarm {
|
||||
unsigned seconds = -1;
|
||||
std::string message;
|
||||
};
|
||||
|
||||
using AlarmPtr = std::unique_ptr<Alarm>;
|
||||
|
||||
void
|
||||
alarmHandler(AlarmPtr alarm)
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::seconds(alarm->seconds));
|
||||
std::cout << alarm->message << "\n";
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
{
|
||||
std::string line;
|
||||
|
||||
while (true) {
|
||||
std::cout << "Alarm> ";
|
||||
|
||||
std::getline(std::cin, line);
|
||||
if (!std::cin.good())
|
||||
exit(0);
|
||||
|
||||
if (line.empty())
|
||||
continue;
|
||||
|
||||
std::stringstream in(line);
|
||||
|
||||
AlarmPtr alarm(new Alarm());
|
||||
in >> alarm->seconds;
|
||||
alarm->message = in.str();
|
||||
|
||||
if (alarm->seconds < 1 || alarm->message.empty()) {
|
||||
std::cout << "Bad command\n";
|
||||
continue;
|
||||
}
|
||||
|
||||
std::thread t(alarmHandler, std::move(alarm));
|
||||
t.detach();
|
||||
}
|
||||
}
|
||||
24
src/errors.h
24
src/errors.h
@@ -1,11 +1,11 @@
|
||||
#ifndef __errors_h
|
||||
#define __errors_h
|
||||
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/*
|
||||
* Define a macro that can be used for diagnostic output from
|
||||
@@ -35,14 +35,24 @@
|
||||
* 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)); \
|
||||
#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)); \
|
||||
#define errno_abort(text) \
|
||||
do { \
|
||||
fprintf(stderr, \
|
||||
"%s at \"%s\":%d: %s\n", \
|
||||
text, \
|
||||
__FILE__, \
|
||||
__LINE__, \
|
||||
strerror(errno)); \
|
||||
abort(); \
|
||||
} while (0)
|
||||
|
||||
|
||||
21
src/errors.hpp
Normal file
21
src/errors.hpp
Normal file
@@ -0,0 +1,21 @@
|
||||
|
||||
#ifndef SRC_ERRORS_HPP_
|
||||
#define SRC_ERRORS_HPP_
|
||||
|
||||
#include <exception>
|
||||
#include <iostream>
|
||||
|
||||
#define err_abort(code, text) \
|
||||
do { \
|
||||
std::cerr << text << " at \"" << __FILE__ << ":" << __LINE__ \
|
||||
<< ": error no:" << code << std::endl; \
|
||||
std::terminate(); \
|
||||
} while (false)
|
||||
|
||||
#define errno_abort(text) \
|
||||
do { \
|
||||
std::cerr << text << " at \"" << __FILE__ << ":" << __LINE__ << std::endl; \
|
||||
std::terminate(); \
|
||||
} while (false)
|
||||
|
||||
#endif // SRC_ERRORS_HPP_
|
||||
Reference in New Issue
Block a user