Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
D
dlib
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
钟尚武
dlib
Commits
73156146
Commit
73156146
authored
Jul 22, 2016
by
Davis King
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added dlib::async() and default_thread_pool()
parent
bdbc8e41
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
248 additions
and
2 deletions
+248
-2
CMakeLists.txt
dlib/CMakeLists.txt
+1
-0
source.cpp
dlib/all/source.cpp
+1
-0
thread_pool.cpp
dlib/test/thread_pool.cpp
+2
-2
threads.cpp
dlib/test/threads.cpp
+28
-0
threads.h
dlib/threads.h
+6
-0
async.cpp
dlib/threads/async.cpp
+42
-0
async.h
dlib/threads/async.h
+101
-0
async_abstract.h
dlib/threads/async_abstract.h
+67
-0
No files found.
dlib/CMakeLists.txt
View file @
73156146
...
...
@@ -184,6 +184,7 @@ if (NOT TARGET dlib)
threads/threads_kernel_2.cpp
threads/threads_kernel_shared.cpp
threads/thread_pool_extension.cpp
threads/async.cpp
timer/timer.cpp
stack_trace.cpp
)
...
...
dlib/all/source.cpp
View file @
73156146
...
...
@@ -26,6 +26,7 @@
#if __cplusplus >= 201103
#include "../dnn/cpu_dlib.cpp"
#include "../dnn/tensor_tools.cpp"
#include "../threads/async.cpp"
#endif
#ifndef DLIB_ISO_CPP_ONLY
...
...
dlib/test/thread_pool.cpp
View file @
73156146
...
...
@@ -87,11 +87,11 @@ namespace
add_functor
f
;
for
(
int
num_threads
=
0
;
num_threads
<
4
;
++
num_threads
)
{
future
<
int
>
a
,
b
,
c
,
res
,
d
;
dlib
::
future
<
int
>
a
,
b
,
c
,
res
,
d
;
thread_pool
tp
(
num_threads
);
print_spinner
();
future
<
some_struct
>
obj
;
dlib
::
future
<
some_struct
>
obj
;
for
(
int
i
=
0
;
i
<
4
;
++
i
)
...
...
dlib/test/threads.cpp
View file @
73156146
...
...
@@ -19,6 +19,31 @@ namespace
logger
dlog
(
"test.threads"
);
void
test_async
()
{
print_spinner
();
auto
v1
=
dlib
::
async
([]()
{
dlib
::
sleep
(
500
);
return
1
;
}).
share
();
auto
v2
=
dlib
::
async
([
v1
]()
{
dlib
::
sleep
(
400
);
return
v1
.
get
()
+
1
;
}).
share
();
auto
v3
=
dlib
::
async
([
v2
](
int
a
)
{
dlib
::
sleep
(
300
);
return
v2
.
get
()
+
a
;
},
2
).
share
();
auto
v4
=
dlib
::
async
([
v3
]()
{
dlib
::
sleep
(
200
);
return
v3
.
get
()
+
1
;
});
DLIB_TEST
(
v4
.
get
()
==
5
);
print_spinner
();
auto
except
=
dlib
::
async
([](){
dlib
::
sleep
(
300
);
throw
error
(
"oops"
);
});
bool
got_exception
=
false
;
try
{
except
.
get
();
}
catch
(
error
&
e
)
{
got_exception
=
true
;
DLIB_TEST
(
e
.
what
()
==
string
(
"oops"
));
}
DLIB_TEST
(
got_exception
);
}
class
threads_tester
:
public
tester
{
public
:
...
...
@@ -66,6 +91,8 @@ namespace
DLIB_TEST
(
!
failure
);
test_async
();
}
void
thread_end_handler
(
...
...
@@ -118,6 +145,7 @@ namespace
}
dlog
<<
LTRACE
<<
"ending of thread num "
<<
num
;
}
}
a
;
...
...
dlib/threads.h
View file @
73156146
...
...
@@ -23,5 +23,11 @@
#include "threads/read_write_mutex_extension.h"
#include "threads/parallel_for_extension.h"
// things that require C++11
#if __cplusplus >= 201103
#include "threads/async.h"
#endif
#endif // DLIB_THREADs_
dlib/threads/async.cpp
0 → 100644
View file @
73156146
// Copyright (C) 2016 Davis E. King (davis@dlib.net)
// License: Boost Software License See LICENSE.txt for the full license.
#ifndef DLIB_AsYNC_CPP_
#define DLIB_AsYNC_CPP_
#include "async.h"
#include <stdlib.h>
#include "../string.h"
namespace
dlib
{
// ----------------------------------------------------------------------------------------
namespace
impl
{
unsigned
long
default_num_threads
()
{
try
{
char
*
nt
=
getenv
(
"DLIB_NUM_THREADS"
);
if
(
nt
)
return
string_cast
<
unsigned
long
>
(
nt
);
}
catch
(
string_cast_error
&
)
{}
return
std
::
thread
::
hardware_concurrency
();
}
}
// ----------------------------------------------------------------------------------------
thread_pool
&
default_thread_pool
()
{
static
thread_pool
tp
(
impl
::
default_num_threads
());
return
tp
;
}
}
// ----------------------------------------------------------------------------------------
#endif // DLIB_AsYNC_CPP_
dlib/threads/async.h
0 → 100644
View file @
73156146
// Copyright (C) 2016 Davis E. King (davis@dlib.net)
// License: Boost Software License See LICENSE.txt for the full license.
#ifndef DLIB_AsYNC_Hh_
#define DLIB_AsYNC_Hh_
#include "async_abstract.h"
#include "thread_pool_extension.h"
#include <future>
#include <functional>
namespace
dlib
{
// ----------------------------------------------------------------------------------------
namespace
impl
{
template
<
typename
T
>
struct
selector
{};
template
<
typename
T
,
typename
U
,
typename
V
>
void
call_prom_set_value
(
T
&
prom
,
U
&
fun
,
selector
<
V
>
)
{
prom
.
set_value
(
fun
());
}
template
<
typename
T
,
typename
U
>
void
call_prom_set_value
(
T
&
prom
,
U
&
fun
,
selector
<
void
>
)
{
fun
();
prom
.
set_value
();
}
}
// ----------------------------------------------------------------------------------------
thread_pool
&
default_thread_pool
();
// ----------------------------------------------------------------------------------------
template
<
typename
Function
,
typename
...
Args
>
std
::
future
<
typename
std
::
result_of
<
Function
(
Args
...)
>::
type
>
async
(
thread_pool
&
tp
,
Function
&&
f
,
Args
&&
...
args
)
{
auto
prom
=
std
::
make_shared
<
std
::
promise
<
typename
std
::
result_of
<
Function
(
Args
...)
>::
type
>>
();
std
::
future
<
typename
std
::
result_of
<
Function
(
Args
...)
>::
type
>
ret
=
prom
->
get_future
();
using
bind_t
=
decltype
(
std
::
bind
(
std
::
forward
<
Function
>
(
f
),
std
::
forward
<
Args
>
(
args
)...));
auto
fun
=
std
::
make_shared
<
bind_t
>
(
std
::
bind
(
std
::
forward
<
Function
>
(
f
),
std
::
forward
<
Args
>
(
args
)...));
tp
.
add_task_by_value
([
fun
,
prom
]()
{
try
{
impl
::
call_prom_set_value
(
*
prom
,
*
fun
,
impl
::
selector
<
typename
std
::
result_of
<
Function
(
Args
...)
>::
type
>
());
}
catch
(...)
{
prom
->
set_exception
(
std
::
current_exception
());
}
});
return
std
::
move
(
ret
);
}
// ----------------------------------------------------------------------------------------
template
<
typename
Function
,
typename
...
Args
>
std
::
future
<
typename
std
::
result_of
<
Function
(
Args
...)
>::
type
>
async
(
Function
&&
f
,
Args
&&
...
args
)
{
return
async
(
default_thread_pool
(),
std
::
forward
<
Function
>
(
f
),
std
::
forward
<
Args
>
(
args
)...);
}
}
// ----------------------------------------------------------------------------------------
#ifdef NO_MAKEFILE
#include "async.cpp"
#endif
#endif // DLIB_AsYNC_Hh_
dlib/threads/async_abstract.h
0 → 100644
View file @
73156146
// Copyright (C) 2016 Davis E. King (davis@dlib.net)
// License: Boost Software License See LICENSE.txt for the full license.
#undef DLIB_AsYNC_ABSTRACT_Hh_
#ifdef DLIB_AsYNC_ABSTRACT_Hh_
#include "thread_pool_extension_abstract.h"
#include <future>
#include <functional>
namespace
dlib
{
// ----------------------------------------------------------------------------------------
thread_pool
&
default_thread_pool
(
);
/*!
ensures
- returns a reference to a global thread_pool. If the DLIB_NUM_THREADS
environment variable is set to an integer then the thread pool will contain
DLIB_NUM_THREADS threads, otherwise it will contain
std::thread::hardware_concurrency() threads.
!*/
// ----------------------------------------------------------------------------------------
template
<
typename
Function
,
typename
...
Args
>
std
::
future
<
typename
std
::
result_of
<
Function
(
Args
...)
>::
type
>
async
(
thread_pool
&
tp
,
Function
&&
f
,
Args
&&
...
args
);
/*!
requires
- f must be a function and f(args...) must be a valid expression.
ensures
- This function behaves just like std::async(std::launch::async, f, args)
except that instead of spawning a new thread to process each task it submits
the task to the provided dlib::thread_pool. Therefore, dlib::async() is
guaranteed to use a bounded number of threads unlike std::async(). This also
means that calls to dlib::async() will block if there aren't any free threads
in the thread pool.
!*/
// ----------------------------------------------------------------------------------------
template
<
typename
Function
,
typename
...
Args
>
std
::
future
<
typename
std
::
result_of
<
Function
(
Args
...)
>::
type
>
async
(
Function
&&
f
,
Args
&&
...
args
);
/*!
ensures
- Calling this function is equivalent to directly calling async(default_thread_pool(), f, args...)
!*/
}
// ----------------------------------------------------------------------------------------
#endif // DLIB_AsYNC_ABSTRACT_Hh_
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment