C++ 11 threading error - multithreading

I have a C++11 program that gives me this error:
terminate called after throwing an instance of 'std::system_error'
what(): Operation not permitted
Code:
const int popSize=100;
void initializePop(mt3dSet mt3dPop[], int index1, int index2, std::string ssmName, std::string s1, std::string s2, std::string s3, std::string s4, std::string mt3dnam, std::string obf1, int iNSP, int iNRM, int iNCM, int iNLY, int iOPT, int iNPS, int iNWL, int iNRO, int ssmPosition, int obsPosition ){
if((index1 >= index2)||index1<0||index2>popSize){
std::cout<<"\nInitializing population...\nIndex not valid..\nQuitting...\n";
exit(1);
}
for(int i=index1; i<index2; i++){
mt3dPop[i].setSSM(ssmName, iNSP, iNRM, iNCM, iNLY);
mt3dPop[i].setNam(toString(s1,s3,i));
mt3dPop[i].setObsName(toString(s1,s4,i));
mt3dPop[i].setSsmName(toString(s1,s2,i));
mt3dPop[i].getSSM().generateFl(toString(s1,s2,i),iOPT,iNPS);
mt3dPop[i].generateNam(mt3dnam, ssmPosition, obsPosition);
mt3dPop[i].setFitness(obf1, iNWL, iNRO);
}}
void runPackage(ifstream& inFile){
//all variables/function parameters for function call are read from inFile
unsigned int numThreads = std::thread::hardware_concurrency();// =4 in my computer
std::vector<std::thread> vt(numThreads-1);//three threads
for(int j=0; j<numThreads-1; j++){
vt[j]= std::thread(initializePop,mt3dPop,j*popSize/numThreads, (j+1)*popSize/numThreads, ssmName, s1,s2, s3, s4, mt3dnam,obf1,iNSP, iNRM, iNCM, iNLY, iOPT, iNPS, iNWL, iNRO, ssmPosition, obsPosition ); //0-24 in thread 1, 25-49 in thread 2, 50-74 in thread 3
}
//remaining 75 to 99 in main thread
initializePop(mt3dPop,(numThreads-1)*popSize/numThreads, popSize, ssmName, s1,s2, s3, s4, mt3dnam,obf1,iNSP, iNRM, iNCM, iNLY, iOPT, iNPS, iNWL, iNRO, ssmPosition, obsPosition);
for(int j=0; j<numThreads-1; j++){
vt[j].join();
}}
What does the error mean and how do I fix it?

You need to link correctly, and compile with -std=c++11 - see this example.
I'm guessing you had the same problem as me! (I compiled with -pthread and -std=c++11 rather than linking with those two. (But you will need to compile with std=c++11 as well as linking with it.))
Probably you want to do something like this:
g++ -c <input_files> -std=c++11
then
g++ -o a.out <input_files> -std=c++11 -pthread
... at least I think that's right. (Someone to confirm?)

How to reproduce these errors:
#include <iostream>
#include <stdlib.h>
#include <string>
using namespace std;
void task1(std::string msg){
cout << "task1 says: " << msg;
}
int main() {
std::thread t1(task1, "hello");
t1.join();
return 0;
}
Compile and run:
el#defiant ~/foo4/39_threading $ g++ -o s s.cpp
s.cpp: In function ‘int main()’:
s.cpp:9:3: error: ‘thread’ is not a member of ‘std’
s.cpp:9:15: error: expected ‘;’ before ‘t1’
You forgot to #include <thread>, include it and try again:
#include <iostream>
#include <stdlib.h>
#include <string>
#include <thread>
using namespace std;
void task1(std::string msg){
cout << "task1 says: " << msg;
}
int main() {
std::thread t1(task1, "hello");
t1.join();
return 0;
}
Compile and run:
el#defiant ~/foo4/39_threading $ g++ -o s s.cpp -std=c++11
el#defiant ~/foo4/39_threading $ ./s
terminate called after throwing an instance of 'std::system_error'
what(): Operation not permitted
Aborted (core dumped)
More errors, as you defined above, because you didn't specify -pthread in the compile:
el#defiant ~/foo4/39_threading $ g++ -o s s.cpp -pthread -std=c++11
el#defiant ~/foo4/39_threading $ ./s
task1 says: hello
Now it works.

Related

__attribute__((weak)) doesn't work

I have wrote below code:
#include<stdio.h>
#include<pthread.h>
int pthread_create(
pthread_t*,
const pthread_attr_t *,
void* (*)(void *),
void*) __attribute__ ((weak)) ;
int main(){
if (pthread_create) {
printf("multi-thread");
} else {
printf("single-thread");
}
}
When compiling the code with different ways and running it, it shows the same consequence . The codes are undermentioned:
zoushengfu#zoushengfudeMacBook-Pro:~/Documents/code/c++$ gcc -o pt
pthread.cpp
zoushengfu#zoushengfudeMacBook-Pro:~/Documents/code/c++$ ./pt
multi-thread
zoushengfu#zoushengfudeMacBook-Pro:~/Documents/code/c++$ gcc -o pt pthread.cpp -lpthread
zoushengfu#zoushengfudeMacBook-Pro:~/Documents/code/c++$ ./pt
multi-thread
I want to know why the result is same wheather I use library pthread when compile it. And do I some error when using __attribute__((weak))

Libicu, undefined reference while compiling

I'm trying to use the lib icu in my shared library.
So i generate my .so who use libicu functions, this parts works well.
Then i try to compile my main program, using the shared library that i created before. But i get the following error:
release//libstring.so: undefined reference to `u_errorName_53'
release//libstring.so: undefined reference to `ucnv_toUnicode_53'
release//libstring.so: undefined reference to `ucnv_close_53'
release//libstring.so: undefined reference to `ucnv_fromUChars_53'
release//libstring.so: undefined reference to `udat_open_53'
release//libstring.so: undefined reference to `udat_parse_53'
release//libstring.so: undefined reference to `udat_format_53'
release//libstring.so: undefined reference to `ucnv_toUChars_53'
release//libstring.so: undefined reference to `ucnv_open_53'
release//libstring.so: undefined reference to `udat_close_53'
I have installed the libicu with this help.
I compile my shared library with -licuuc, as well as my main program compile only with -l:libstring.so and -licuuc.
When i do ldd libstring.so, i don't have the .so of the libicu on the list of dependencies.
The problem probably come from this.
Thx
EDIT: I have create a little test:
icu.h:
#pragma once
#include <iostream>
#include <string>
#include <unicode/ucnv.h>
class c_icu
{
private:
void * p_priv;
public:
c_icu();
void open(const wchar_t *name);
void to_local(std::wstring &, std::wstring &);
void from_local(std::wstring &, std::wstring &);
void close(void);
~c_icu();
};
icu.cpp:
#include "icu.h"
c_icu::c_icu()
{
p_priv = NULL;
}
c_icu::~c_icu()
{
if (p_priv)
close();
}
void c_icu::open(const wchar_t *name)
{
UErrorCode status = U_ZERO_ERROR;
char conv_name[256];
if (wcstombs(conv_name, name, 256) == (size_t)-1)
{
std::cout << "ERROR: wcstombs failed" << std::endl;
exit(0);
}
if ((p_priv = (UConverter *)ucnv_open(conv_name, &status)) == NULL)
{
std::cout << "ERROR: ucnv_open failed" << std::endl;
exit(0);
}
}
void c_icu::to_local(std::wstring &src, std::wstring &dst)
{
UErrorCode status = U_ZERO_ERROR;
int32_t len;
len = ucnv_toUChars((UConverter *)p_priv, (UChar *)NULL, 0, (const char *)src.c_str(), src.size(), &status);
if (status == U_BUFFER_OVERFLOW_ERROR)
{
status = U_ZERO_ERROR;
dst.resize(len);
len = ucnv_toUChars((UConverter *)p_priv, (UChar *)dst.c_str(), dst.size(), (const char *)src.c_str(), src.size(), &status);
if (U_FAILURE(status))
{
std::cout << "ERROR: to_local failed" << std::endl;
exit(0);
}
}
}
void c_icu::from_local(std::wstring &src, std::wstring &dst)
{
UErrorCode status = U_ZERO_ERROR;
int32_t len;
len = ucnv_fromUChars((UConverter *)p_priv, (char *)NULL, 0, (const UChar *)src.c_str(), src.size(), &status);
if (status == U_BUFFER_OVERFLOW_ERROR)
{
status = U_ZERO_ERROR;
dst.reserve(len);
len = ucnv_fromUChars((UConverter *)p_priv, (char *)dst.c_str(), dst.size(), (const UChar *)src.c_str(), -1, &status);
}
}
void c_icu::close(void)
{
ucnv_close((UConverter *)p_priv);
p_priv = NULL;
}
test.cpp:
#include "icu.h"
int main(void)
{
c_icu converter;
std::wstring src = L"";
std::wstring dst;
const wchar_t add[11] = L"Just a test";
const wchar_t *unicode = L"koi8-r";
for (unsigned int i = 0; i < 1000; i++)
src.append(add, 11);
converter.open(unicode);
converter.from_local(src, dst);
converter.close();
}
Makefile:
NAME= test
LIB_NAME= libicutest.so
FLAGS= -W -Wall -Wextra
all: lib $(NAME)
$(NAME):
#echo "Main programm compiling ..."
g++ -c test.cpp -o test.o $(FLAGS)
g++ -o $(NAME) test.o -Wl,-rpath,'$$ORIGIN/' -licui18n -L. -licutest
#echo "Main programm compiled"
lib:
#echo "Lib Compiling ..."
g++ -std=gnu++11 -c -fPIC icu.cpp -o icu.o $(FLAGS)
g++ -shared -Wl,-soname,$(LIB_NAME) -o $(LIB_NAME) icu.o -licui18n
#echo "Lib Compiled"
Note: even with -licuuc instead of -licui18n i got the same error.
Output:
$> make
Lib Compiling ...
g++ -std=gnu++11 -c -fPIC icu.cpp -o icu.o -W -Wall -Wextra
g++ -shared -Wl,-soname,libicutest.so -o libicutest.so icu.o -licui18n
Lib Compiled
Main programm compiling ...
g++ -c test.cpp -o test.o -W -Wall -Wextra
g++ -o test test.o -Wl,-rpath,'$ORIGIN/' -licui18n -L. -licutest
./libicutest.so: undefined reference to `ucnv_close_53'
./libicutest.so: undefined reference to `ucnv_fromUChars_53'
./libicutest.so: undefined reference to `ucnv_toUChars_53'
./libicutest.so: undefined reference to `ucnv_open_53'
collect2: error: ld returned 1 exit status
make: *** [test] Error 1
If i do ldd on my shared library:
$> ldd libicutest.so
linux-vdso.so.1 => (0x00007ffd5eb7f000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f092b5e6000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f092b221000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f092af1a000)
/lib64/ld-linux-x86-64.so.2 (0x00007f092bb00000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f092ad04000)
EDIT2:
Ok, seems that the problem is easier to solve than expected. My program need function in icu_53, but i got icu_48 installed on my computer dunno why.
$> locate libicu
/usr/lib/x86_64-linux-gnu/libicudata.so.48
/usr/lib/x86_64-linux-gnu/libicudata.so.48.1.1
/usr/lib/x86_64-linux-gnu/libicui18n.so.48
/usr/lib/x86_64-linux-gnu/libicui18n.so.48.1.1
/usr/lib/x86_64-linux-gnu/libicuio.so.48
/usr/lib/x86_64-linux-gnu/libicuio.so.48.1.1
/usr/lib/x86_64-linux-gnu/libicule.so.48
/usr/lib/x86_64-linux-gnu/libicule.so.48.1.1
/usr/lib/x86_64-linux-gnu/libiculx.so.48
/usr/lib/x86_64-linux-gnu/libiculx.so.48.1.1
/usr/lib/x86_64-linux-gnu/libicutest.so.48
/usr/lib/x86_64-linux-gnu/libicutest.so.48.1.1
/usr/lib/x86_64-linux-gnu/libicutu.so.48
/usr/lib/x86_64-linux-gnu/libicutu.so.48.1.1
/usr/lib/x86_64-linux-gnu/libicuuc.so.48
/usr/lib/x86_64-linux-gnu/libicuuc.so.48.1.1
Does anyone know how to upgrade the version from icu_48 to icu_53 at least ?
Seems 'udat_parse_53' is located inside libicui18n.so.53 library. Try to compile your project with '-licui18n' option.

Issue with dlopen and weak symbols

I have the following sequence
executable (main) ---- (dlopen)---> libapp.so ---(dynamically linked)--> libfoo.so
libfoo.so in turn dynamically links to libfoo_strong.so. libfoo.so invokes a function from
libfoo_strong.so, but also has a weak definition (within foo.c which is compiled into libfoo.so).
Now, libapp.so invokes a function from libfoo.so (say invoke_foo_func_ptr() and this function >invokes a function pointer which stores the symbol that is defined as weak. My expectation is that >invokes_foo_func_ptr invokes the strong symbol, but it always goes to the weak symbol. Pls see the >code below for details.
PS: Dont ask me to explain the reason particular sequence of execution, but I am open to >workarounds.
foo_strong.c --> gcc -g -fPIC -shared -rdynamic foo_strong.o -o libfoo_strong.so
foo.c: --> gcc -g -fPIC -shared -rdynamic -L/users/ardesiga/cprogs/ld_r foo.o -o libfoo.so
app.c: --> gcc -g -fPIC -shared -rdynamic -L/users/ardesiga/cprogs/ld_r -lfoo -lfoo_strong app.o -o > libapp.so
/* foo_strong.c */
int
foo_weak_func (char *msg)
{
printf("[%s:%s] Reached strong, with msg: %s\n", __FILE__, __FUNCTION__, msg);
}
/* foo.c */
#include <stdio.h>
#include <stdlib.h>
#include "foo_ext.h"
#include "foo_weak.h"
int __attribute__ ((weak)) foo_weak_func (char *msg)
{
printf("[%s:%s], Reached weak, with msg: %s\n", __FILE__, __FUNCTION__, msg);
}
typedef int (*func_ptr_t) (char *msg);
func_ptr_t foo_func_ptr = foo_weak_func;
void
invoke_foo_func_ptr (char *msg)
{
printf("Inside %s\n", __FUNCTION__);
if (foo_func_ptr) {
(*foo_func_ptr)(msg);
} else {
printf("foo_func_ptr is NULL\n");
}
}
/* app.c */
#include "foo.h"
int
app_init_func (char *msg)
{
printf("Inside %s:%s\n", __FILE__, __FUNCTION__);
invoke_foo_func_ptr(msg);
}
/* main.c */
int main (int argc, char *argv[])
{
void *dl_handle;
char *lib_name;
app_init_func_t app_init_func;
if (!(argc > 1)) {
printf("Library is not supplied, loading libapp.so\n");
lib_name = strdup("libapp.so");
} else {
lib_name = strdup(argv[2]);
}
printf("Loading library: %s\n", lib_name);
dl_handle = dlopen(lib_name, RTLD_LAZY);
if (!dl_handle) {
printf("Failed to dlopen on %s, error: %s\n", lib_name, dlerror());
exit(1);
}
app_init_func = dlsym(dl_handle, "app_init_func");
if (app_init_func) {
(*app_init_func)("Called via dlsym");
} else {
printf("dlsym did not file app_init_func");
}
return (0);
}
My expectation is that invokes_foo_func_ptr invokes the strong symbol, but it always goes to the weak symbol.
Your expectation is incorrect and everything is working as designed.
Weak symbols lose to strong symbols when you link a single ELF binary. If you were to link a normal (strong) function foo and a weak foo into libfoo.so, the the strong definition would have won.
When you have multiple ELF images, some with strong foo, and some with weak foo, the first ELF image to define foo (regardless of whether weak or strong) wins. The loader will simply not look for any additional ELF images in its search scope once it finds the first image that does provide a definition for foo.
Dont ask me to explain the reason particular sequence of execution
That is quite an obnoxious thing to say.
I have a guess as to what your reason may be, and a solution for it, but you'll have to provide your reason first.

C++11 alternative to OpenMP with clang

Clang doesn't support OpenMP (yet) but is it possible to implement a "parallel for" with C++11 ?
OpenMP version :
// parallelfor_gcc.cpp
// g++ -O2 -Wall -std=c++11 -fopenmp parallelfor_gcc.cpp
#include <cmath>
#include <vector>
int main() {
unsigned int size = 1e8;
std::vector<double> vect(size);
#pragma omp parallel for
for (unsigned int i=0; i<size; i++) {
vect[i] = sin(2*M_PI*i/(double)size);
}
return 0;
}
C++11 version:
// parallelfor_clang.cpp
// clang++ -O4 -Wall -std=c++11 -lpthread parallelfor_clang.cpp
#include <cmath>
#include <thread>
#include <vector>
void parallelFor(const unsigned int size,
std::function<void(const unsigned int)> func) {
const unsigned int nbThreads = std::thread::hardware_concurrency();
std::vector < std::thread > threads;
for (unsigned int idThread = 0; idThread < nbThreads; idThread++) {
auto threadFunc = [=, &threads]() {
for (unsigned int i=idThread; i<size; i+=nbThreads) {
func(i);
}
};
threads.push_back(std::thread(threadFunc));
}
for (auto & t : threads) t.join();
}
int main() {
unsigned int size = 1e8;
std::vector<double> vect(size);
auto myFunc = [=, &vect](unsigned int i){
vect[i] = sin(2*M_PI*i/(double)size);
};
parallelFor(size, myFunc);
return 0;
}
OpenMP clauses (firstprivate...) can be implemented in the same way but it's (a little) more work...

GLIB: g_atomic_int_get becomes NO-OP?

In a larger piece of code, I noticed that the g_atomic_* functions in glib were not doing what I expected, so I wrote this simple example:
#include <stdlib.h>
#include "glib.h"
#include "pthread.h"
#include "stdio.h"
void *set_foo(void *ptr) {
g_atomic_int_set(((int*)ptr), 42);
return NULL;
}
int main(void) {
int foo = 0;
pthread_t other;
if (pthread_create(&other, NULL, set_foo, &foo)== 0) {
pthread_join(other, NULL);
printf("Got %d\n", g_atomic_int_get(&foo));
} else {
printf("Thread did not run\n");
exit(1);
}
}
When I compile this with GCC's '-E' option (stop after pre-processing), I notice that the call to g_atomic_int_get(&foo) has become:
(*(&foo))
and g_atomic_int_set(((int*)ptr), 42) has become:
((void) (*(((int*)ptr)) = (42)))
Clearly I was expecting some atomic compare and swap operations, not just simple (thread-unsafe) assignments. What am I doing wrong?
For reference my compile command looks like this:
gcc -m64 -E -o foo.E `pkg-config --cflags glib-2.0` -O0 -g foo.c
The architecture you are on does not require a memory barrier for atomic integer set/get operations, so the transformation is valid.
Here's where it's defined: http://git.gnome.org/browse/glib/tree/glib/gatomic.h#n60
This is a good thing, because otherwise you'd need to lock a global mutex for every atomic operation.

Resources