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))
|
PROGRAMS_C=$(addprefix $(BIN)/, $(NAMES_C))
|
||||||
|
|
||||||
SOURCES_CXX=\
|
SOURCES_CXX=\
|
||||||
|
ch01/alarm_cpp.cpp \
|
||||||
|
ch01/alarm_fork_cpp.cpp \
|
||||||
|
ch01/alarm_thread_cpp.cpp \
|
||||||
ch03/alarm_mutex_cpp.cpp \
|
ch03/alarm_mutex_cpp.cpp \
|
||||||
ch04/pipe_cpp.cpp
|
ch04/pipe_cpp.cpp
|
||||||
|
|
||||||
@@ -77,7 +80,7 @@ all: format dirs ${PROGRAMS_C} ${PROGRAMS_CXX}
|
|||||||
|
|
||||||
format:
|
format:
|
||||||
#clang-format -i $(SOURCE)/*.c*
|
#clang-format -i $(SOURCE)/*.c*
|
||||||
#clang-format -i $(SOURCE)/*.h*
|
clang-format -i $(SOURCE)/*.h*
|
||||||
clang-format -i $(SOURCE)/*/*.c*
|
clang-format -i $(SOURCE)/*/*.c*
|
||||||
clang-format -i $(SOURCE)/*/*.h*
|
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);
|
free(alarm);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char* argv[])
|
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
|
#ifndef __errors_h
|
||||||
#define __errors_h
|
#define __errors_h
|
||||||
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Define a macro that can be used for diagnostic output from
|
* 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
|
* a ";" following the ")" in the do...while construct, err_abort and
|
||||||
* errno_abort can be used as if they were function calls.
|
* errno_abort can be used as if they were function calls.
|
||||||
*/
|
*/
|
||||||
#define err_abort(code,text) do { \
|
#define err_abort(code, text) \
|
||||||
fprintf (stderr, "%s at \"%s\":%d: %s\n", \
|
do { \
|
||||||
text, __FILE__, __LINE__, strerror (code)); \
|
fprintf(stderr, \
|
||||||
|
"%s at \"%s\":%d: %s\n", \
|
||||||
|
text, \
|
||||||
|
__FILE__, \
|
||||||
|
__LINE__, \
|
||||||
|
strerror(code)); \
|
||||||
abort(); \
|
abort(); \
|
||||||
} while (0)
|
} while (0)
|
||||||
#define errno_abort(text) do { \
|
#define errno_abort(text) \
|
||||||
fprintf (stderr, "%s at \"%s\":%d: %s\n", \
|
do { \
|
||||||
text, __FILE__, __LINE__, strerror (errno)); \
|
fprintf(stderr, \
|
||||||
|
"%s at \"%s\":%d: %s\n", \
|
||||||
|
text, \
|
||||||
|
__FILE__, \
|
||||||
|
__LINE__, \
|
||||||
|
strerror(errno)); \
|
||||||
abort(); \
|
abort(); \
|
||||||
} while (0)
|
} 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