• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1[/
2          Copyright Oliver Kowalke 2017.
3 Distributed under the Boost Software License, Version 1.0.
4    (See accompanying file LICENSE_1_0.txt or copy at
5          http://www.boost.org/LICENSE_1_0.txt
6]
7
8[#worker]
9[section:worker Running with worker threads]
10
11[heading Keep workers running]
12
13If a worker thread is used but no fiber is created or parts of the framework
14(like __yield__) are touched, then no fiber scheduler is instantiated.
15
16        auto worker = std::thread(
17                []{
18                    // fiber scheduler not instantiated
19                });
20        worker.join();
21
22
23If ['use_scheduling_algorithm<>()] is invoked, the fiber scheduler is created.
24If the worker thread simply returns, destroys the scheduler and terminates.
25
26        auto worker = std::thread(
27                []{
28                    // fiber scheduler created
29                    boost::fibers::use_scheduling_algorithm<my_fiber_scheduler>();
30                });
31        worker.join();
32
33
34In order to keep the worker thread running, the fiber associated with the thread
35stack (which is called ["main] fiber) is blocked. For instance the ["main] fiber
36might wait on a __condition__. For a gracefully shutdown __condition__ is
37signalled and the ["main] fiber returns. The scheduler gets destructed if all
38fibers of the worker thread have been terminated.
39
40        boost::fibers::mutex mtx;
41        boost::fibers::condition_variable_any cv;
42        auto worker = std::thread(
43                [&mtx,&cv]{
44                    mtx.lock();
45                    // suspend till signalled
46                    cv.wait(mtx);
47                    mtx.unlock();
48                });
49        // signal termination
50        cv.notify_all();
51        worker.join();
52
53
54[heading Processing tasks]
55
56Tasks can be transferred via channels. The worker thread runs a pool of fibers
57that dequeue and executed tasks from the channel. The termination is signalled via
58closing the channel.
59
60        using task = std::function<void()>;
61        boost::fibers::buffered_channel<task> ch{1024};
62        auto worker = std::thread(
63                [&ch]{
64                    // create pool of fibers
65                    for (int i=0; i<10; ++i) {
66                        boost::fibers::fiber{
67                            [&ch]{
68                                task tsk;
69                                // dequeue and process tasks
70                                while (boost::fibers::channel_op_status::closed!=ch.pop(tsk)){
71                                    tsk();
72                                }
73                            }}.detach();
74                    }
75                    task tsk;
76                    // dequeue and process tasks
77                    while (boost::fibers::channel_op_status::closed!=ch.pop(tsk)){
78                        tsk();
79                    }
80                });
81        // feed channel with tasks
82        ch.push([]{ ... });
83        ...
84        // signal termination
85        ch.close();
86        worker.join();
87
88
89An alternative is to use a work-stealing scheduler. This kind of scheduling
90algorithm a worker thread steals fibers from the ready-queue of other worker
91threads if its own ready-queue is empty.
92
93[note Wait till all worker threads have registered the work-stealing scheduling
94algorithm.]
95
96        boost::fibers::mutex mtx;
97        boost::fibers::condition_variable_any cv;
98        // start wotrker-thread first
99        auto worker = std::thread(
100                [&mtx,&cv]{
101                    boost::fibers::use_scheduling_algorithm<boost::fibers::algo::work_stealing>(2);
102                    mtx.lock();
103                    // suspend main-fiber from the worker thread
104                    cv.wait(mtx);
105                    mtx.unlock();
106                });
107        boost::fibers::use_scheduling_algorithm<boost::fibers::algo::work_stealing>(2);
108        // create fibers with tasks
109        boost::fibers::fiber f{[]{ ... }};
110        ...
111        // signal termination
112        cv.notify_all();
113        worker.join();
114
115
116[important Because the TIB (thread information block on Windows) is not fully
117described in the MSDN, it might be possible that not all required TIB-parts are
118swapped. Using WinFiber implementation might be an alternative (see documentation
119about [@http://www.boost.org/doc/libs/1_65_1/libs/context/doc/html/context/cc/implementations__fcontext_t__ucontext_t_and_winfiber.html
120['implementations fcontext_t, ucontext_t and WinFiber of boost.context]]).]
121
122
123[endsect]
124