I'm getting this error when I compile with g++ thread.cpp -o thread -lpthread and I can't seem to find the referencing error:
Undefined first referenced
symbol in file
sem_destroy /var/tmp//ccfHWR7G.o
sem_init /var/tmp//ccfHWR7G.o
sem_post /var/tmp//ccfHWR7G.o
sem_wait /var/tmp//ccfHWR7G.o
ld: fatal: symbol referencing errors. No output written to thread
collect2: ld returned 1 exit status
My header file just contains some global variables and function names:
#ifndef THREAD_H_
#define THREAD_H_
#define NUM_THREADS 6
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <iostream>
#include <semaphore.h>
#include <fstream>
#include <unistd.h>
using namespace std;
sem_t SEM;
fstream of;
pthread_t thread[NUM_THREADS];
pthread_attr_t attr;
int rc;
long t;
void *status;
void *Busy_Work(void *t);
void Open_Initialize_File();
void Initialize_Set_Attribute();
void Create_Thread();
void Free_Attricutes_Wait();
#endif /* THREAD_H_ */
This is my main file and check with an IDE there wasn't any basic syntax that I missed:
#include "thread.h"
int main (int argc, char *argv[]) {
Open_Initialize_File();
Initialize_Set_Attribute();
Create_Thread();
Free_Attricutes_Wait();
sem_destroy(&SEM);
cout << "Main: program completed" << endl << "Exiting" << endl;
pthread_exit(NULL);
}
void Open_Initialize_File() {
of.open("SHARED.txt");
of << pthread_self() << "\r" << endl;
of.close();
}
void Initialize_Set_Attribute() {
sem_init(&SEM, 0, 1);
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_JOINABLE);
}
void Create_Thread() {
for (int t = 0; t < NUM_THREADS; t++) {
rc = pthread_create(&thread[t], &attr, Busy_Work, (void *)(t+1));
if (rc) {
cout << "ERROR: return code from pthread_create() is " << rc << endl;
exit(-1);
}
}
}
void *Busy_Work(void *t) {
int i;
long tid = (long)t;
for (i=0; i<10; i++)
{
sem_wait(&SEM);
cout << "Thread" << tid << "Thread id< " << pthread_self() << " >running..." << endl;
of.open("SHARED.txt",std::fstream::app);//opening file in append mode
of << pthread_self() << "\r" << endl;
of.close();
sem_post(&SEM);
if(tid%2==0)
sleep(2);
else
sleep(3);
}
pthread_exit((void*) t);
}
void Free_Attricutes_Wait() {
pthread_attr_destroy(&attr);
for (t = 0; t < NUM_THREADS; t++) {
rc = pthread_join(thread[t], &status);
if (rc) {
cout << "ERROR: return code from pthread_join() is" << rc << endl;
exit(-1);
}
cout << "Thread " << t << " Thread id <" << pthread_self() << ">exited" << endl;
}
}
The linker is missing some symbols, that might indicate that some additional external library needs to be linked as well. On a unix platform a good way to figure out how to fix this is to have a look at the man pages:
man sem_init
This will usually tell you what you need to do. In this case it would specify that you need to link with -lrt
Related
I have a code, main thread create 2 thread(thread_1 and thread_2), I use pthread_cancel to cancel thread_1 in thread_2, but the data that I create in thread_1 will not be destructored when I run it in QNX system, but there is no problem in Linux system.
It my test code, when I run it in QNX system,MyClass and MyClass2 object destructor not be called, so the 100M memory will leak; but run it in Linux system,it will call MyClass and MyClass2 object destructor. why is there such a difference???
#include <iostream>
#include <pthread.h>
#include <thread>
using namespace std;
pthread_t thread_id_1;
pthread_t thread_id_2;
class MyClass2
{
public:
MyClass2() {
cout << "Build MyClass2" << endl;
}
~MyClass2() {
cout << "Destory MyClass2" << endl;
}
};
class MyClass
{
public:
MyClass() {
cout << "Build MyClass" << endl;
p = (char *)malloc(1024 * 1024 *100);
}
~MyClass() {
cout << "Destory MyClass" << endl;
free(p);
}
char *p;
};
void func(int i)
{
MyClass2 c2;
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
cout << "thread 1 func:" << i << endl;
}
static void *thread_1(void *arg)
{
MyClass my_class;
int type_value = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
cout << "thread_1 set cancle type+++++:" << type_value << endl;
for (int i = 0; i < 10; i++) {
func(i);
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
}
return nullptr;
}
static void *thread_2(void *arg)
{
for (int i = 0; i < 10; i++) {
cout << "thread_2:" << i << endl;
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
int ret = pthread_cancel(thread_id_1);
cout << "otx_thread_2 cancel thread 1 ret:" << ret << endl;
return nullptr;
}
int main(int argc, char *argv[])
{
cout << "Main start" << endl;
pthread_attr_t attr;
pthread_attr_init( &attr );
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
cout << "Main set detch" << endl;
if (pthread_create(&thread_id_1, &attr, thread_1, nullptr) != 0) {
cout << "pthread_create() 1 error" << endl;
return -1;
}
if (pthread_create(&thread_id_2, nullptr, thread_2, nullptr) != 0) {
cout << "pthread_create() 2 error" << endl;
return -1;
}
if (pthread_join(thread_id_2, NULL) != 0) {
cout << "pthread_join() 1 error";
return -1;
}
while (1) {
cout << "Main Loop" << endl;
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
}
return 0;
}
enter image description here
enter image description here
I try it again and again, so I confirm that there is no problem with the code, But I don't understand why there is such a difference
pthread_cancel is outside the scope of the C++ specification. C++ does not specify its behavior, nor inherit it from C or POSIX.
The difference is simply because QNX and Linux have implemented pthread_cancel differently in a C++ environment. There is literally nothing more to it than that.
I imagine that the QNX implementation stops the thread in its tracks, whereas the Linux implementation probably induces an exception which unwinds the canceled thread's stack.
My program must to search a file by name from some directory and search it through the threads!
Here I created TEMP folder for testing this search,included some different files and here searching for example ".cpp" file.But the problem is not here.
The compiler says "must return a value from ThreadSearch", and I've tried many return statements ,but all of it is not suitable,All that i found on internet cannot fix this error,and nobody has an error like in my code,I reckon this is a bug and in the void function it shoud be normal "return;" ,but it does not work and help, in other cases I got errors like "unresolved symbol",maybe somebody can help me with this!
here's my code!
#include <iostream>
//#include<fileapi.h>
#include <pthread.h>
#include <stdlib.h>
#include <windows.h>
using namespace std;
#define thread_max 8
HANDLE FindFile;
WIN32_FIND_DATA FindFileData;
LPCWSTR file = L"D:\\VS-studio\\TEMP\\*.cpp";
void* ThreadSearch(void* args)
{
int current_thread = 0;
int num = current_thread++;
for (int i = num * (8 / 4); i < ((num + 1) * (8 / 4)); i++)
{
FindFile = FindFirstFile(file, &FindFileData);
}
// return (void*)current_thread;
// pthread_exit(nullptr);
return;
}
int main(int argc, char* argv[])
{
pthread_t thread[thread_max];
for (int i = 0; i < thread_max; i++)
{
pthread_create(&thread[i], NULL, &ThreadSearch, (NULL));
}
for (int i = 0; i < thread_max; i++)
{
(pthread_join(thread[i], NULL));
}
void pthread_exit(void* retval);
if (INVALID_HANDLE_VALUE == FindFile)
{
cout << "error in finding file" << endl;
cout << "Error" << GetLastError() << endl;
}
else
{
cout << "File found" << endl;
wcout << "File name - " << FindFileData.cFileName << endl;
wcout << "File size - " << FindFileData.nFileSizeLow << endl;
}
return 0;
}
my project use three Level process mode. In order to the code after the fork does not inherit from the worker thread of the previous process, so create sub thread to fork sub process when each called.
Now, I found some problems at following describe:
1. the grandson process create a std::thread(work_thread), when called the join() method, it's throw a exception
2. if the son process dose not in sub thread call fork() method, then it's does not thow exception
3. if in grandson process create a empty std::thread(it's nothing to do) before the work thread create, and the empty thread called join() method after the work thread called join() , then it is does not throw the exception. but if the empty thread called join() before work thread, it's also throw the same exception
if you can help me, please write your answer, i will thank you very much
the following code is test case:
#include <iostream>
#include <unistd.h>
#include <wait.h>
#include <thread>
using namespace std;
int main(int argc, char **argv)
{
std::thread t([]() {
int l2pid = fork();
if(l2pid > 0)
waitpid(l2pid, NULL, 0);
else if (l2pid == 0)
{
std::thread t2([]() {
int l3pid = fork();
if (l3pid > 0)
waitpid(l3pid, NULL, 0);
else if (l3pid == 0){
//std::thread empty_thread([](){
//});
std::thread work_thread([](){
for(int i = 0; i < 5; i++){
std::cout << "working..." << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(1));
}
});
if(work_thread.joinable())
work_thread.join();
//if(empty_thread.joinable())
// empty_thread.join();
std::cout << "L3 Process Exit!" << std::endl;
}
});
if (t2.joinable())
t2.join();
std::cout << "L2 Process Exit!" << std::endl;
}
});
if (t.joinable())
t.join();
std::cout << "Main Process Exit!" << std::endl;
return 0;
}
i use pthread_create and pthread_join also return EDEADLK
#include <iostream>
#include <unistd.h>
#include <wait.h>
#include <thread>
#include <vector>
#include <pthread.h>
using namespace std;
void *work_thread(void *)
{
for (int i = 0; i < 5; i++)
{
std::cout << "working..." << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(1));
}
return NULL;
}
void *t2_function(void *)
{
int l3pid = fork();
if (l3pid > 0)
{
waitpid(l3pid, NULL, 0);
}
else if (l3pid == 0)
{
pthread_t thread_handle;
int ret = pthread_create(&thread_handle, NULL, work_thread, NULL);
std::this_thread::sleep_for(std::chrono::seconds(3));
void *pthread_ret = NULL;
std::cout << "thread_handle:" << thread_handle << ",pthread_self:" << pthread_self() << std::endl;
ret = pthread_join(thread_handle, &pthread_ret);
std::cout << "pthread_join:" << ret << std::endl;
std::cout << "L3 Process Exit!" << std::endl;
}
}
void * t1_function(void *)
{
int l2pid = fork();
if (l2pid > 0)
waitpid(l2pid, NULL, 0);
else if (l2pid == 0)
{
pthread_t l2;
pthread_create(&l2, NULL, t2_function, NULL);
pthread_join(l2, NULL);
std::cout << "L2 Process Exit!" << std::endl;
}
}
int main(int argc, char **argv)
{
pthread_t l1;
pthread_create(&l1, NULL, t1_function, NULL);
pthread_join(l1, NULL);
std::cout << "L1 Process Exit!" << std::endl;
return 0;
}
How to initialized pthread_t variable in class constructor.
C++ Static Analysis(coverity) Error: Non-static class member threadId is not initialized in this constructor nor in any functions that it calls.
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>
void *
threadFunc(void * arg)
{
std::cout << "Thread Function :: Start" << std::endl;
// Sleep for 2 seconds
sleep(2);
std::cout << "Thread Function :: End" << std::endl;
return NULL;
}
class threads
{
private:
pthread_t threadId;
int err;
public:
threads():err(0){};
~threads(){};
void create_thread();
void join_thread();
};
void
threads::create_thread()
{
// Create a thread that will function threadFunc()
err = pthread_create(&threadId, NULL, &threadFunc, NULL);
// Check if thread is created sucessfuly
if (err)
{
std::cout << "Thread creation failed : " << strerror(err);
}
else
{
std::cout << "Thread Created with ID : " << threadId << std::endl;
}
}
void
threads::join_thread()
{
err = pthread_join(threadId, NULL);
// check if joining is sucessful
if (err)
{
std::cout << "Failed to join Thread : " << strerror(err) << std::endl;
}
}
int main()
{
threads T;
T.create_thread();
T.join_thread();
std::cout << "Exiting Main" << std::endl;
return 0;
}
Note:
I have checked all existing questions and answer in Stackoverflow.
But none of them have clear answer.
The above c++ code is a sample code(copied from Internet and updated to show my actual problem)
I have tried this and its working (Posting the answer, to help others)
#include <iostream>
#include <string.h>
#include <pthread.h>
#include <unistd.h>
void *
threadFunc(void * arg)
{
std::cout << "Thread Function :: Start" << std::endl;
// Sleep for 2 seconds
sleep(2);
std::cout << "Thread Function :: End" << std::endl;
return NULL;
}
class threads
{
private:
pthread_t threadId;
int err;
public:
threads():err(0){ threadId = pthread_t(); std::cout <<threadId<<std::endl;};
~threads(){};
void create_thread();
void join_thread();
};
void
threads::create_thread()
{
// Create a thread that will function threadFunc()
err = pthread_create(&threadId, NULL, &threadFunc, NULL);
// Check if thread is created sucessfuly
if (err)
{
std::cout << "Thread creation failed : " << strerror(err);
}
else
{
std::cout << "Thread Created with ID : " << threadId << std::endl;
}
}
void
threads::join_thread()
{
err = pthread_join(threadId, NULL);
// check if joining is sucessful
if (err)
{
std::cout << "Failed to join Thread : " << strerror(err) << std::endl;
}
}
int main()
{
threads T;
T.create_thread();
T.join_thread();
std::cout << "Exiting Main" << std::endl;
return 0;
}
What's meaning of field uc_stack in struct ucontext_t?Who use it? The coroutine or the coroutine's signal handler? How can I test it? For example
#include <iostream>
#include <ucontext.h>
#include <queue>
#include <signal.h>
using namespace std;
void sigHandler(int signo)
{
printf("sigHandler:%x\n", &signo);
exit(-1);
}
queue<int> qProduct;
void consumer(ucontext_t* pConsumer, ucontext_t* pProducer)
{
char a[SIGSTKSZ] = {0};
while(1)
{
if(qProduct.size() > 0)
{
cout << __FUNCTION__ << "|" << qProduct.front() << endl;
qProduct.pop();
}
else
{
cout << pConsumer << "|" << pProducer << endl;
swapcontext(pConsumer, pProducer);
}
}
}
void producer(ucontext_t* pConsumer, ucontext_t* pProducer, bool* pFinished)
{
for(int i=0; i<10; i++)
{
if(qProduct.size() < 5)
{
qProduct.push(i);
cout << __FUNCTION__ << "|" << i << endl;
}
else
{
cout << pConsumer << "|P|" << pProducer << endl;
swapcontext(pProducer, pConsumer);
}
}
cout << pConsumer << "|P|" << pProducer << endl;
swapcontext(pProducer, pConsumer);
*pFinished = true;
}
int main(int argc, char* argv[])
{
ucontext_t Main, Consumer, Producer;
/* The stack for the iterator function. */
char consumer_stack[SIGSTKSZ];
char producer_stack[SIGSTKSZ];
cout << "SIGSTKSZ:" << SIGSTKSZ << endl;
/* Flag indicating that the iterator has completed. */
volatile bool bFinished = false;
getcontext(&Consumer);
Consumer.uc_link = &Main;
Consumer.uc_stack.ss_sp = consumer_stack;
Consumer.uc_stack.ss_size = sizeof(consumer_stack);
makecontext(&Consumer, (void (*)(void))consumer, 2, &Consumer, &Producer);
getcontext(&Producer);
Producer.uc_link = &Main;
Producer.uc_stack.ss_sp = producer_stack;
Producer.uc_stack.ss_size = sizeof(producer_stack);
makecontext(&Producer, (void (*)(void))producer, 3, &Consumer, &Producer, &bFinished);
if(!bFinished)
{
swapcontext(&Main, &Producer);
}
return 0;
}
Who use the stack "consumer_stack", "consumer" or "sigHandler"?How to prove it?