Commit 3a0a35ab9099ab3fbcfd3ee27d02b3b2f86cc9ee

Authored by Grzegorz Jabłoński
1 parent f68ef015

Multithreaded server

12-threads.cpp 0 → 100644
  1 +/* multithreads.cpp */
  2 +#include <asio/ts/io_context.hpp>
  3 +#include <asio/ts/net.hpp>
  4 +#include <asio/ts/socket.hpp>
  5 +
  6 +#include <iostream>
  7 +
  8 +int a = 0;
  9 +
  10 +void WorkerThread(std::shared_ptr<asio::io_context> io_svc, int counter) {
  11 + std::cout << counter << ".\n";
  12 + io_svc->run();
  13 + std::cout << "End.\n";
  14 +}
  15 +
  16 +int main(void) {
  17 +
  18 + auto io_svc = std::make_shared<asio::io_context>();
  19 +
  20 + auto worker = std::make_shared<asio::io_context::work>(*io_svc);
  21 +
  22 + std::cout << "Press ENTER key to exit!" << std::endl;
  23 +
  24 + std::vector<std::thread> threads;
  25 + for (int i = 0; i < 5; i++)
  26 + threads.emplace_back(WorkerThread, io_svc, i);
  27 +
  28 + io_svc->post([] { std::cout << "Hello\n"; });
  29 +
  30 + std::cin.get();
  31 +
  32 + io_svc->stop();
  33 +
  34 + for (auto &i : threads)
  35 + i.join();
  36 +
  37 + return 0;
  38 +}
0 39 \ No newline at end of file
... ...
13-daytime8.cpp 0 → 100644
  1 +//
  2 +// server.cpp
  3 +// ~~~~~~~~~~
  4 +//
  5 +// Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com)
  6 +//
  7 +// Distributed under the Boost Software License, Version 1.0. (See accompanying
  8 +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  9 +//
  10 +
  11 +#include <asio.hpp>
  12 +#include <ctime>
  13 +#include <iostream>
  14 +#include <string>
  15 +
  16 +using asio::ip::tcp;
  17 +
  18 +std::shared_ptr<asio::io_context> io_context;
  19 +
  20 +std::string make_daytime_string() {
  21 + using namespace std; // For time_t, time and ctime;
  22 + time_t now = time(0);
  23 +
  24 + sleep(10);
  25 +
  26 + char buf[26];
  27 + return ctime_r(&now, buf);
  28 +}
  29 +
  30 +class tcp_connection : public std::enable_shared_from_this<tcp_connection> {
  31 +public:
  32 + typedef std::shared_ptr<tcp_connection> pointer;
  33 +
  34 + static pointer create(asio::io_context &io_context) {
  35 + return pointer(new tcp_connection(io_context));
  36 + }
  37 +
  38 + tcp::socket &socket() { return socket_; }
  39 +
  40 + void start() {
  41 + io_context->post([self = shared_from_this()] {
  42 + self->message_ = make_daytime_string();
  43 + asio::async_write(self->socket_, asio::buffer(self->message_),
  44 + std::bind(&tcp_connection::handle_write, self,
  45 + std::placeholders::_1,
  46 + std::placeholders::_2));
  47 + });
  48 + }
  49 +
  50 +private:
  51 + tcp_connection(asio::io_context &io_context) : socket_(io_context) {}
  52 +
  53 + void handle_write(const asio::error_code & /*error*/,
  54 + size_t /*bytes_transferred*/) {
  55 + std::cout << "Written!" << std::endl;
  56 + }
  57 +
  58 + tcp::socket socket_;
  59 + std::string message_;
  60 +};
  61 +
  62 +class tcp_server {
  63 +public:
  64 + tcp_server(asio::io_context &io_context)
  65 + : io_context_(io_context),
  66 + acceptor_(io_context, tcp::endpoint(tcp::v4(), 13)) {
  67 + start_accept();
  68 + }
  69 +
  70 +private:
  71 + void start_accept() {
  72 + tcp_connection::pointer new_connection =
  73 + tcp_connection::create(io_context_);
  74 +
  75 + acceptor_.async_accept(new_connection->socket(),
  76 + std::bind(&tcp_server::handle_accept, this,
  77 + new_connection, std::placeholders::_1));
  78 + }
  79 +
  80 + void handle_accept(tcp_connection::pointer new_connection,
  81 + const asio::error_code &error) {
  82 + if (!error) {
  83 + new_connection->start();
  84 + }
  85 +
  86 + start_accept();
  87 + }
  88 +
  89 + asio::io_context &io_context_;
  90 + tcp::acceptor acceptor_;
  91 +};
  92 +
  93 +void WorkerThread(std::shared_ptr<asio::io_context> io_svc) {
  94 + io_svc->run();
  95 +}
  96 +
  97 +int main() {
  98 + try {
  99 + io_context = std::make_shared<asio::io_context>();
  100 +
  101 + auto worker = std::make_shared<asio::io_context::work>(*io_context);
  102 +
  103 + std::vector<std::thread> threads;
  104 +
  105 + for (int i = 0; i < 5; i++)
  106 + threads.emplace_back(WorkerThread, io_context);
  107 +
  108 + tcp_server server(*io_context);
  109 +
  110 + for (auto &i : threads)
  111 + i.join();
  112 +
  113 + } catch (std::exception &e) {
  114 + std::cerr << e.what() << std::endl;
  115 + }
  116 +
  117 + return 0;
  118 +}
... ...
makefile
... ... @@ -4,7 +4,7 @@ CFLAGS=-ggdb -Wall -pedantic -D_REENTRANT -DASIO_STANDALONE -DASIO_HAS_CO_AWAIT
4 4 %: %.cpp
5 5 g++-10 -std=c++20 -fcoroutines $(CFLAGS) $< -o $@ -lpthread
6 6  
7   -EXECS = 00-timer1 01-timer2 02-timer3 03-timer4 04-timer5 05-daytime1 06-daytime2 07-daytime3 08-daytime4 09-daytime5 10-daytime6 11-daytime7
  7 +EXECS = 00-timer1 01-timer2 02-timer3 03-timer4 04-timer5 05-daytime1 06-daytime2 07-daytime3 08-daytime4 09-daytime5 10-daytime6 11-daytime7 12-threads 13-daytime8
8 8  
9 9 all: $(EXECS)
10 10  
... ...