While creating a static library using c++11, it fails during linking I think.
I can create a static library and link to it using the information in How to create a static library with g++? with ordinary c++, but if I try to follow the steps using c++11 features, it fails during the linking.
test.cpp:
#include <iostream>
#include <vector>
#include "libtestlib.h"
using namespace std;
int main() {
itest n1={{1,2,3,4},
{5,6,7,8},
{9,0,1,2}};
cout << "testing...\n";
test_print(n1);
return 0;
}
libtestlib.h:
#ifndef testlib
#define testlib
#include <vector>
using namespace std;
typedef vector<vector<double>> dtest;
typedef vector<vector<int>> itest;
template <typename testtype>
void test_print(testtype);
#endif
libtestlib.cpp:
#include <iostream>
#include "libtestlib.h"
using namespace std;
template <typename testtype>
void test_print(testtype &t)
{
int m=t.size();
int n=t[0].size();
for(int i=0; i<m; i++) {
for(int j=0; j<n; j++)
cout << t[i][j] << " ";
cout << endl;
}
cout << endl;
}
this is the output I'm getting:
$ g++ -std=c++11 -c libtestlib.cpp
$ ar rvs libtestlib.a libtestlib.o
r - libtestlib.o
$ g++ -std=c++11 test.cpp libtestlib.a
/tmp/cccJ7SXZ.o:test.cpp:(.text+0x1af): undefined reference to `void test_print<std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > > >(std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > >)'
/tmp/cccJ7SXZ.o:test.cpp:(.text+0x1af): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `void test_print<std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > > >(std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > >)'
collect2: error: ld returned 1 exit status
Since it seems you are supporting operations on a limited number of types, the classic "Just do it in a header" answer to this problem is not necessarily the best one.
You can get the best of both worlds by explicitely exporting a symbol for each implementation, but delegate the implementation to a template within the library:
libtestlib.h:
#ifndef testlib
#define testlib
#include <vector>
using namespace std;
typedef vector<vector<double>> dtest;
typedef vector<vector<int>> itest;
void test_print(dtest&);
void test_print(itest&);
libtestlib.cpp:
#include <iostream>
#include "libtestlib.h"
using namespace std;
namespace {
template <typename testtype>
void test_print_impl(testtype &t)
{
int m=t.size();
int n=t[0].size();
for(int i=0; i<m; i++) {
for(int j=0; j<n; j++)
cout << t[i][j] << " ";
cout << endl;
}
cout << endl;
}
}
void test_print(dtest& val) {
test_print_impl(val);
}
void test_print(itest& val) {
test_print_impl(val);
}
Mind you, for a small function like this, it's probably not worth the effort, and just inlining the template code in the header is just fine. At what point does the complexity of a function and the scope of its dependencies warrant this is a bit of a judgement call.
Putting example requested from comment on the question here as code looked really ugly in a comment. Combined libtestlib.h and libtestlib.cpp
#ifndef testlib
#define testlib
#include <vector>
#include <iostream>
using namespace std;
typedef vector<vector<double>> dtest;
typedef vector<vector<int>> itest;
template <typename testtype>
void test_print(testtype &t)
{
int m=t.size();
int n=t[0].size();
for(int i=0; i<m; i++) {
for(int j=0; j<n; j++)
cout << t[i][j] << " ";
cout << endl;
}
cout << endl;
}
#endif
Related
I am using code that runs on ARM (not Intel processor). Running c++11 code example (CODE A) from: http://www.cplusplus.com/reference/condition_variable/condition_variable/wait_for/ to test the wait_for() mechanism. This is not working right - looks like the wait_for() does not wait. In Intel works fine. After some research and using pthread library directly and setting MONOTONIC_CLOCK definition, solves the issue (CODE B).
(Running on ARM is not the issue)
My problem is :
How can I force the C++11 API wait_for() to work with MONOTONIC_CLOCK?
Actually I would like to stay with 'CODE A' but with the support or setting of MONOTONIC_CLOCK.
Thanks
CODE A
// condition_variable::wait_for example
#include <iostream> // std::cout
#include <thread> // std::thread
#include <chrono> // std::chrono::seconds
#include <mutex> // std::mutex, std::unique_lock
#include <condition_variable> // std::condition_variable, std::cv_status
std::condition_variable cv;
int value;
void read_value() {
std::cin >> value;
cv.notify_one();
}
int main ()
{
std::cout << "Please, enter an integer (I'll be printing dots): \n";
std::thread th (read_value);
std::mutex mtx;
std::unique_lock<std::mutex> lck(mtx);
while
(cv.wait_for(lck,std::chrono::seconds(1))==std::cv_status::timeout)
{
std::cout << '.' << std::endl;
}
std::cout << "You entered: " << value << '\n';
th.join();
return 0;
}
CODE B
#include <sys/time.h>
#include <unistd.h>
#include <iostream> // std::cout
#include <thread> // std::thread
#include <chrono> // std::chrono::seconds
#include <mutex> // std::mutex, std::unique_lock
#include <condition_variable> // std::condition_variable, std::cv_status
const size_t NUMTHREADS = 1;
pthread_mutex_t mutex;
pthread_cond_t cond;
int value;
bool done = false;
void* read_value( void* id )
{
const int myid = (long)id; // force the pointer to be a 64bit integer
std::cin >> value;
done = true;
printf( "[thread %d] done is now %d. Signalling cond.\n", myid, done
);
pthread_cond_signal( &cond );
}
int main ()
{
struct timeval now;
pthread_mutexattr_t Attr;
pthread_mutexattr_init(&Attr);
pthread_mutexattr_settype(&Attr, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init(&mutex, &Attr);
pthread_condattr_t CaAttr;
pthread_condattr_init(&CaAttr);
pthread_condattr_setclock(&CaAttr, CLOCK_MONOTONIC);
pthread_cond_init(&cond, &CaAttr);
std::cout << "Please, enter an integer:\n";
pthread_t threads[NUMTHREADS];
int t = 0;
pthread_create( &threads[t], NULL, read_value, (void*)(long)t );
struct timespec ts;
pthread_mutex_lock( &mutex );
int rt = 0;
while( !done )
{
clock_gettime(CLOCK_MONOTONIC, &ts);
ts.tv_sec += 1;
rt = pthread_cond_timedwait( & cond, & mutex, &ts );
std::cout << "..." << std::endl;
}
pthread_mutex_unlock( & mutex );
std::cout << "You entered: " << value << '\n';
return 0;
}
The documentation for std::condition_variable::wait_for says:
A steady clock is used to measure the duration.
std::chrono::steady_clock:
Class std::chrono::steady_clock represents a monotonic clock. The time points of this clock cannot decrease as physical time moves forward.
Unfortunately, this is gcc Bug 41861 (DR887) - (DR 887)(C++0x) does not use monotonic_clock that it uses system_clock instead of steady_clock for condition variables.
One solution is to use wait_until (be sure to read Notes section) function that allows to specify durations relative to a specific clock. E.g.:
cv.wait_until(lck, std::chrono::steady_clock::now() + std::chrono::seconds(1))
The code below triggers the error:
Error 1 error C2248: 'std::promise<_Ty>::promise' : cannot access private member declared in class 'std::promise<_Ty>'
How can I fix it?
Thanks a lot !
#define _parallel_qick_sort
#ifdef _parallel_qick_sort
#include <boost/shared_ptr.hpp>
#include <thread>
#include <vector>
#include <list>
#include <future>
#include <atomic>
#include "ThreadSafeStack.hpp"
using namespace std;
template<typename T>
struct sorter
{
struct chunk_to_sort
{
std::list<T> data_m;
std::promise<std::list<T> > promise_m;
};
threadsafe_stack<chunk_to_sort> chunks_m;
std::vector<std::thread> threads_m;
unsigned const max_thread_count_m;
std::atomic<bool> end_of_data_m;
sorter():
max_thread_count_m(std::thread::hardware_concurrency()-1),
end_of_data_m(false)
{}
~sorter()
{
end_of_data_m=true;
for(unsigned i=0;i<threads_m.size();++i)
{
threads_m[i].join();
}
}
void try_sort_chunk()
{
boost::shared_ptr<chunk_to_sort > chunk=chunks.pop();
if(chunk)
{
sort_chunk(chunk);
}
}
std::list<T> do_sort(std::list<T>& chunk_data)
{
if(chunk_data.empty())
{
return chunk_data;
}
std::list<T> result;
result.splice(result.begin(),chunk_data,chunk_data.begin());
T const& partition_val=*result.begin();
typename std::list<T>::iterator divide_point = std::partition(chunk_data.begin(),chunk_data.end(),[&](T const& val){return val<partition_val;});
chunk_to_sort new_lower_chunk;
new_lower_chunk.data_m.splice(new_lower_chunk.data_m.end(),chunk_data,chunk_data.begin(),divide_point);
std::future<std::list<T> > new_lower = new_lower_chunk.promise_m.get_future();
chunks_m.push(std::move(new_lower_chunk));
if(threads_m.size()<max_thread_count_m)
{
threads_m.push_back(std::thread(&sorter<T>::sort_thread,this));
}
std::list<T> new_higher(do_sort(chunk_data));
result.splice(result.end(),new_higher);
while(new_lower.wait_for(std::chrono::seconds(0)) !=
std::future_status::ready)
{
try_sort_chunk();
}
result.splice(result.begin(),new_lower.get());
return result;
}
void sort_chunk(boost::shared_ptr<chunk_to_sort > const& chunk)
{
chunk->promise_m.set_value(do_sort(chunk->data));
}
void sort_thread()
{
while(!end_of_data)
{
try_sort_chunk();
std::this_thread::yield();
}
}
};
template<typename T>
std::list<T> parallel_quick_sort(std::list<T> input)
{
if(input.empty())
{
return input;
}
sorter<T> s;
return s.do_sort(input);
}
int main()
{
list<int> l;
l.push_back(4);
l.push_back(3);
l.push_back(1);
l.push_back(2);
parallel_quick_sort(l);
return 0;
}
#endif
Below is threadsafe_stack class:
#ifndef __ThreadSafeStack_hpp__
#define __ThreadSafeStack_hpp__
#include "stdafx.h"
#include <exception>
#include <memory>
#include <mutex>
#include <stack>
#include <thread>
#include <iostream>
#include <functional>
#include <future>
using namespace std;
struct empty_stack : std::exception
{
const char* what() const throw()
{
return "empty stack";
}
};
template <typename T>
class threadsafe_stack
{
std::stack<T> data_m;
mutable std::mutex mutex_m;
threadsafe_stack& operator = (const threadsafe_stack&);
public:
typedef void (threadsafe_stack<T>:: * ext_push) (T);
typedef shared_ptr<T> (threadsafe_stack<T>:: *ext_pop)();
typedef void (threadsafe_stack<T>:: *ext_pop_void)(T& );
typedef bool (threadsafe_stack<T>:: *ext_empty) () const;
threadsafe_stack()
{
int i=0;
}
threadsafe_stack(const threadsafe_stack& other)
{
std::lock_guard<std::mutex> lock(other.mutex_m);
for(int i=0; i<3; ++i)
cout << "threadsafe_stack ctor "<< i << endl;
data_m = other.data_m;
}
void push(T new_value)
{
std::lock_guard<std::mutex> lock(mutex_m);
for(int i=0; i<3; ++i)
cout << "push "<< i << endl;
data_m.push(new_value);
}
std::shared_ptr<T> pop()
{
std::lock_guard<std::mutex> lock(mutex_m);
for(int i=0; i<3; ++i)
cout << "pop "<< i << endl;
if(data_m.empty())
throw empty_stack();
std::shared_ptr<T> const res(std::make_shared<T>(data_m.top()));
data_m.pop();
return res;
}
void pop(T& value)
{
std::lock_guard<std::mutex> lock(mutex_m);
for(int i=0; i<3; ++i)
cout << "pop "<< i << endl;
if(data_m.empty())
throw empty_stack();
value = data_m.top();
data_m.pop();
}
bool empty() const
{
//std::lock_guard<std::mutex> lock(mutex_m);
for(int i=0; i<3; ++i)
cout << "empty "<< i << endl;
return data_m.empty();
}
};
#endif __ThreadSafeStack_hpp__
why this program giving seg fault. I tried figuring out the issue using gdb, but no luck.
#include <iostream>
#include <condition_variable>
#include <thread>
#include <chrono>
using namespace std;
condition_variable cv;
mutex cv_m;
mutex m;
int count = 0;
#define COUNT_DONE 10
#define COUNT_HALT1 3
#define COUNT_HALT2 6
void functionCount1()
{
for(;;)
{
m.lock();
count++;
cout << "Counter value functioncount1: " << count << endl;
m.unlock();
if(count >= COUNT_DONE)
return;
}
}
void functionCount2()
{
for(;;)
{
m.lock();
count++;
cout << "Counter value functionCount2: " << count << endl;
m.unlock();
if(count >= COUNT_DONE) return;
}
}
int main()
{
thread t1(functionCount1), t2(functionCount2);
t1.join();
t2.join();
return 0;
}
Your program has undefined behavior: the accesses to count outside the mutex in functionCount1 and functionCount2 are data races. With the UB corrected, it seems fine:
#include <iostream>
#include <mutex>
#include <thread>
using namespace std;
mutex m;
int count = 0;
#define COUNT_DONE 10
void functionCount(const char* name)
{
for(;;)
{
m.lock();
auto c = ++count;
m.unlock();
cout << "Counter value " << name << ": " << c << endl;
if(c >= COUNT_DONE)
return;
}
}
int main()
{
thread t1(functionCount, "functionCount1"), t2(functionCount, "functionCount2");
t1.join();
t2.join();
}
or if you want to be "clever" and confuse your code reviewers:
void functionCount(const char* name)
{
for(;;)
{
auto c = (std::lock_guard<std::mutex>(m), count++);
cout << "Counter value " << name << ": " << c << endl;
if(c >= count_done)
break;
}
}
So I am trying to use pthread libraries for Visual C++(2012) and I get this error error C4716: 'print_message' : must return a value
Here's the code
#include "stdafx.h"
#include <iostream>
#include "pthread.h"
using namespace std;
void* print_message(void *)
{
cout << "Threading\n";
}
int main()
{
pthread_t t1;
pthread_create(&t1, NULL, print_message, NULL);
cout << "Hello";
void* result;
pthread_join(t1,&result);
return 0;
}
Add return NULL; to print_message. I'll bet you need to name the argument too.
Here's my basic boost code
#include <iostream>
#include <boost/thread.hpp>
using namespace boost;
using namespace boost::this_thread;
using namespace std;
// Global function called by thread
void GlobalFunction()
{
for (int i=0;i<10;++i)
{
cout << i << "Do something in parallel with main method." << endl;
boost::this_thread::yield();
}
}
void GlobalThreadTest()
{
boost::thread t(&GlobalFunction);
for (int i = 0; i<10; ++i) {
cout << i << "Do something in main method. " << endl;
}
}
int main(int argc, const char * argv[])
{
GlobalThreadTest();
return 0;
}
I'm getting lots of errors like this from xcode
(null): "boost::this_thread::yield()", referenced from:
(null): "boost::detail::thread_data_base::~thread_data_base()",
referenced from: (null): "boost::system::system_category()",
referenced from: (null): "boost::system::generic_category()",
referenced from: (null): "boost::thread::start_thread()", referenced
from:
I have installed boost using macports and the header search paths in xcode is set to
/opt/local/include/
This contains all the .hpp files.
2 Questions
Does boost create *.o files if so where are they stored?
How do I get xcode 4.2 to work with this boost thread example? If there is a flag I have to set, which parameter in xcode 4.2 do I set it in?
Thanks.