2.4.9. age_threads.cpp#

2.4.9.1. Source code#

 1// University of Florida EEL6528
 2// Tan F. Wong
 3// Jan 8, 2021
 4
 5#include <uhd/utils/safe_main.hpp>
 6#include <uhd/utils/thread.hpp>
 7#include <boost/program_options.hpp>
 8#include <thread>
 9#include <chrono>
10#include <csignal>
11 
12namespace po = boost::program_options;
13
14// Interrupt signal handlers
15static bool stop_signal_called = false;
16void sig_int_handler(int) {
17    stop_signal_called = true;
18}
19
20// worker function to print  age
21void print_age(std::string name, int age, bool nice) {
22    while (not stop_signal_called) {
23        if (nice) {
24            // nice printing
25            if (age < 0) {
26                std::cout << "From Thread #" << std::this_thread::get_id() << ": " << name <<  "'s age is unknown." << std::endl;
27            } else {
28                std::cout << "From Thread #" << std::this_thread::get_id() << ": " << name << " is " << age << " years old." << std::endl;
29            }
30        } else {
31            // not nice printin
32            std::cout << "Thread # = " << std::this_thread::get_id() << ": " << std::endl;
33            std::cout << "Name = " << name << std::endl;
34            std::cout << "Age = " << age << std::endl;
35        }
36        std::this_thread::sleep_for(std::chrono::seconds(1)); // Just don't go too fast
37    }
38}
39
40int UHD_SAFE_MAIN(int argc, char *argv[]) {
41    // Set main thread priority to highest
42    uhd::set_thread_priority_safe(1.0, true);
43 
44    //variables to be set by po
45    std::string name;
46    int age;
47 
48    //setup the program options
49    po::options_description desc("Allowed options");
50    desc.add_options()
51        ("help", "help message")
52        ("name,n", po::value<std::string>(&name)->default_value("This person"), "The person's name")
53        ("age,a", po::value<int>(&age)->default_value(-1), "The person's age")
54        ("nice-print", "Print out the info nicely")
55    ;
56 
57    po::variables_map vm;
58    po::store(po::parse_command_line(argc, argv, desc), vm);
59    po::notify(vm);
60 
61    //print the help message
62    if (vm.count("help")) {
63        std::cout << desc << std::endl;
64        return EXIT_SUCCESS;
65    }
66
67    std::signal(SIGINT, &sig_int_handler);
68
69    // Spawn 10 worker threads
70    int num_threads = 10;
71    std::thread worker[num_threads];
72    for (int i=0; i<num_threads; i++) {
73        worker[i] = std::thread(&print_age, name, age, vm.count("nice-print"));
74    }
75        
76    // Keep running until CTRL-C issued
77    while (not stop_signal_called) {
78        std::this_thread::sleep_for(std::chrono::milliseconds(1)); // sleep for 1ms to make sure can catch CTRL-C
79    }
80
81    // Join all worker threads
82    for (int i=0; i<num_threads; i++) {
83        if (worker[i].joinable()) worker[i].join();
84    }
85
86    std::cout << std::endl;
87    return EXIT_SUCCESS;
88}

2.4.9.2. Build#

  • Need to link the uhd, boost_program_options libraries when compiling:

    g++ age_threads.cpp -o age_threads -luhd -lboost_program_options
    

2.4.9.3. Usage Example#

$ ./age_threads --nice-print --name=Tom -a 25

Experiment

Run the example above to see what happens! Can you explain what you see?