I am trying to pass values recursively with threading.
In my example, I am creating a thread and i pass it some data, and this thread creates another thread recursively, which also passes it some data.
The output is the following:
Thread 1: value = 8
Thread 2: value = 12318230
Why am I not getting the value 4 for the second thread even though I assigned it the value 4?
From my understanding (please correct me if I am wrong), each thread has its own stack. When I pass the value 4 to Thread 2 (the thread created by the first thread), the variable is in memory until the thread ends. Since I have a call to pthread_join, I wait until the child thread ends until I resume. I am uncertain why the value of Thread 2 is some random number.
int count = 0
typedef struct
{
int value;
} ThreadInfo;
void* ChildWork(void* a) {
pthread_t threadid;
count++;
if(count > 2)
pthread_exit(0);
ThreadInfo* info = (ThreadInfo*)a;
printf("value = %d\n", info->value);
ThreadInfo* child = new ThreadInfo;
child->value = 4;
pthread_create(&threadid, NULL, ChildWork, (void*)&child);
pthread_join(threadid, NULL);
pthread_exit(0);
}
int main(int argc, const char *argv[])
{
pthread_t threadid;
ThreadInfo info;
info.value = 8;
pthread_create(&threadid, NULL, ChildWork, (void*)&info);
pthread_join(threadid, NULL);
return 0;
}
ThreadInfo* child = new ThreadInfo;
child->value = 4;
pthread_create(&threadid, NULL, ChildWork, (void*)&child);
&child is a ThreadInfo** but the child thread casts it to a ThreadInfo* and reads garbage. Change (void*)&child to just child.
Related
I have thread creation problem using Pthread. My code is as follows. I show only some portion due to space constraints.
Main.c create Detectdirection instance and send to the function.
d = new Detectdirection();
while(run)
{
int ret = d->run_parallel(d);
if(ret == -1)
run = false;
}
My Detectdirection Class has two functions to run in parallel:
class Detectdirection{
public:
int run_parallel(void*p);
void *Tracking(void *p);
static void *Tracking_helper(void * p);
void *ReadImage(void *p );
static void *ReadImage_helper(void *p );
private:
pthread_t thread[2];
}
void *Detectdirection::ReadImage(void *p){
Detectdirection *app = (Detectdirection*)p;
while(run){
}
pthread_exit(NULL);
}
void *Detectdirection::Tracking(void *p){
Detectdirection *app = (Detectdirection*)p;
while(run){
}
pthread_exit(NULL);
}
void *Detectdirection::Tracking_helper(void *p){
Detectdirection *app = (Detectdirection*)p;
return ((Detectdirection*)p)->Tracking(app);
}
void *Detectdirection::ReadImage_helper(void *p ){
Detectdirection *app = (Detectdirection*)p;
return ((Detectdirection*)p)->ReadImage(app);
}
int Detectdirection::run_parallel(void* p){
Detectdirection *app = (Detectdirection*)p;
int rc = pthread_create(&thread[0], NULL, app->ReadImage_helper, app);
if (rc) {
printf("ERROR; return code from pthread_create() is %d\n", rc);
return -1;
}
rc = pthread_create(&thread[1], NULL, app->Tracking_helper, app);
if (rc) {
printf("ERROR; return code from pthread_create() is %d\n", rc);
return -1;
}
return 0;
}
Compile is ok and when I run, I have thread creation error. That sort of return type 11 happens only when many threads are created. But now I create only two thread and I have that error. What could be wrong?
I believe your are getting EAGAIN (based on the error code 11). That (obivously) means your system doesn't have enough resources to create threads anymore.
POSIX documentation says:
[EAGAIN] The system lacked the necessary resources to create another
thread, or the system-imposed limit on the total number of threads in
a process {PTHREAD_THREADS_MAX} would be exceeded.
I am not quite sure the following is true.
But now I create only two thread and I have that error. What could be wrong?
Here,
while(run)
{
int ret = d->run_parallel(d);
if(ret == -1)
run = false;
}
You are creating in a loop and each call d->run_parallel() creates two threads. So, you are potentially creating infinite number of threads
as the loop only breaks when pthread_create() fails. So, you may want to look at this loop carefully whether you really want to do as it is right now.
You don't seem to join with the threads you create. So, you could detach the threads so that thread-specific resources are released immediately when the thread(s) exit.
You can do:
pthread_detach(pthread_self());
in both ReadImage_helper() and Tracking_helper() functions to detach them. This could potentially solve your resource issue.
If it's still present then you have to look at ways to limit the number of threads that are simultaneously running on your system. One possible option is to use thread pools -- create a fixed number of threads and assign them new tasks as the threads complete their current task(s).
I have a question about C concurrency programming in Embedded System with about 64Mb Ram.
Especially, I want to reduce the default memory used by a Thread, so I have defined:
pthread_attr_t attr_test;
size_t stacksize = 0x186A0; // 100Kbyte
pthread_attr_init(&attr_test);
pthread_attr_setdetachstate(&attr_test, PTHREAD_CREATE_DETACHED);
pthread_attr_setstacksize(&attr_test, stacksize);
So, When the Thread starts, it uses only 100Kbyte of virtual Memory.
BUT when the Thread ends and calls pthread_exit, the virtual Memory used by the process, increases rapidly!....
Why? What can I do?
Thanks!
UPDATE:
Thread ->
void *thread_test(void *arg1) {
int *param;
param = (int*)arg1;
printf("Thread %d start\n", *param);
pthread_cond_wait(&condition[*param], &mutex[*param]);
printf("Thread %d stop\n",*param);
pthread_exit(0);
}
Main ->
int main(void) {
pthread_t IDthread[MAX_THREADS];
int param[MAX_THREADS];
int pointer;
int i, keyb;
void *stkaddr;
size_t stacksize;
puts("!!! THREAD TEST !!!");
printf("Process ID %d\n\n", getpid());
for(i=0; i<MAX_THREADS; i++)
{
pthread_cond_init(&condition[i], NULL);
pthread_mutex_init(&mutex[i], NULL);
IDthread[i] = 0;
param[i] = i;
}
stacksize = 0x186A0; // 100Kbyte
pthread_attr_init(&attr_test);
pthread_attr_setdetachstate(&attr_test, PTHREAD_CREATE_DETACHED);
/* setting the size of the stack also */
pthread_attr_setstacksize(&attr_test, stacksize);
pointer = 0;
do {
keyb = getchar();
if (keyb == '1')
{
if (pointer < MAX_THREADS)
{
pthread_create(&IDthread[pointer], &attr_test, thread_test, ¶m[pointer]);
sleep(1);
pointer++;
}
else
puts("MAX Threads Number");
}
if (keyb == '2')
{
if (pointer != 0)
{
pointer--;
pthread_cond_signal(&condition[pointer]);
sleep(1);
}
else
puts("0 Thread is running");
}
} while (keyb != '0');
printf("FINE\n");
return EXIT_SUCCESS;
}
There is a known issue with the joinable or detached threads, quoting from the manual:
Only when a
terminated joinable thread has been joined are the last of its
resources released back to the system. When a detached thread
terminates, its resources are automatically released back to the
system
you can make the thread detachable with:
pthread_attr_setdetachstate(3)
There are some problems with your test.
At first, pthread_attr_setstacksize has the following documentation:
The stack size attribute determines the minimum size (in bytes) that will be allocated for threads created using the thread attributes object attr.
So each thread could use more than what you have set. But more than that, threads may allocate memory from the OS to use as stack. And this also applies to the main thread.
Therefore I don't think there is a way to achieve what you want by looking at the result of top command, since this information is only visible from within the thread itself.
Also note that the virtual memory used by the process is not related to the amount of RAM used by the process.
Here is something you can try to check the total stack of a thread.
=)
i am a new user here, and I am new to c++, so it is a bit hard for me to work on it...
so i am asking you guys some questions! =)
i am doing a work for school, that asks me to implement threading priority into this:
#include <pthread.h>
#include <stdio.h>
#include <sched.h>
int sched_yield(void);
// Parameters to print_function.
struct char_print_parms{
char character; // char to print
int count; // times to print
};
void* char_print (void* parameters){
int i;
struct char_print_parms* p;
p = (struct char_print_parms*) parameters;
for (i = 0; i < p->count; ++i){
fputc (p->character, stderr);
sched_yield();
}
return NULL;
}
int main (){
pthread_t thread1_id,thread2_id;
struct char_print_parms thread1_args,thread2_args;
// Create a new thread to print 200 x's.
thread1_args.character = 'x';
thread1_args.count = 200;
pthread_create (&thread1_id, NULL, &char_print, &thread1_args);
// Create a new thread to print 200 o's.
thread2_args.character = 'o';
thread2_args.count = 200;
pthread_create (&thread2_id, NULL,
&char_print, &thread2_args);
// main waits for the threads to complete
pthread_join(thread1_id, NULL);
pthread_join(thread2_id, NULL);
return 0;
}
This gives is "oxoxoxo..." etc.
The objective is to get more "o", until it finishes.
What I did was:
#include <pthread.h>
#include <stdio.h>
#include <sched.h>
int sched_yield(void);
// Parameters to print_function.
struct char_print_parms{
char character; // char to print
int count; // times to print
};
void* char_print (void* parameters){
int i;
struct char_print_parms* p;
p = (struct char_print_parms*) parameters;
for (i = 0; i < p->count; ++i){
fputc (p->character, stderr);
sched_yield();
}
return NULL;
}
int main (){
pthread_t thread1_id,thread2_id;
struct char_print_parms thread1_args,thread2_args;
//new code lines
struct sched_param param;
pthread_attr_t pta;
pthread_attr_init(&pta);
pthread_attr_getschedparam(&pta, ¶m);
//end of new code lines
// Create a new thread to print 200 x's.
thread1_args.character = 'x';
thread1_args.count = 200;
//more new code lines
param.sched_priority = 0;
pthread_attr_setschedparam(&pta, ¶m);
pthread_setschedparam(thread1_id, SCHED_OTHER, ¶m);
//end of more new code lines
pthread_create (&thread1_id, NULL, &char_print, &thread1_args);
// Create a new thread to print 200 o's.
thread2_args.character = 'o';
thread2_args.count = 200;
//more new code lines 2
param.sched_priority = 10;
pthread_attr_setschedparam(&pta, ¶m);
pthread_setschedparam(thread2_id, SCHED_OTHER, ¶m);
//end of more new code lines 2
pthread_create (&thread2_id, NULL,
&char_print, &thread2_args);
// main waits for the threads to complete
pthread_join(thread1_id, NULL);
pthread_join(thread2_id, NULL);
return 0;
}
At the end, I compile and try to run, but it appears an error:
Segmentation failed (core dumped)
Once again, I am new to c++ and my english is not very good, but I want to try to understand why this does not work. Any help is welcome!
When you call pthread_setschedparam the thread id variables haven't been initialized yet. So you're trying to change parameters on an indeterminate thread.
The easiest way to change the priority is to do it in the thread themselves.
Regarding uninitialized local variables, their values are indeterminate until explicitly initialized. Using uninitialized local variables leads to undefined behavior.
If you see the example in the pthread_setschedparam you see it being called with pthread_self to set the own threads priority. You can use this to either add a field in the structure you pass to the thread that contains the priority, or have a wrapper thread-function which sets the priority and then calls the actual thread function.
You should first call pthread_create (&thread1_id, NULL, &char_print, &thread1_args); to create thread thread1_id, then you can set this thread's priority. I modify the code and it works fine.
thread1_args.character = 'x';
thread1_args.count = 200;
pthread_create (&thread1_id, NULL, &char_print, &thread1_args);
//more new code lines
param.sched_priority = 0;
pthread_attr_setschedparam(&pta, ¶m);
pthread_setschedparam(thread1_id, SCHED_OTHER, ¶m);
// Create a new thread to print 200 o's.
thread2_args.character = 'o';
thread2_args.count = 200;
pthread_create (&thread2_id, NULL, &char_print, &thread2_args);
//more new code lines 2
param.sched_priority = 10;
pthread_attr_setschedparam(&pta, ¶m);
pthread_setschedparam(thread2_id, SCHED_OTHER, ¶m);
You can read this link:https://access.redhat.com/site/documentation/en-US/Red_Hat_Enterprise_MRG/2/html/Realtime_Reference_Guide/chap-Realtime_Reference_Guide-Priorities_and_policies.html.
I test this code, but the output is different each time.
I have a program that is trying to use create and cancel through an implemented pool.
The creation is as follows:
int threadsNum=10;
while (created<threadsNum){
pthread_t newThread;
pthread_struct *st; //Open the thread that handle the deleting of the sessions timeout.
st = (pthread_struct*)malloc(sizeof(pthread_struct));
st->id = created;
st->t = newThread;
pthread_mutex_lock( &mutex_threadsPool );
readingThreadsPool[created] = st;
pthread_mutex_unlock( &mutex_threadsPool );
if((threadRes1 = pthread_create( &newThread, NULL, pcapReadingThread, (void*)created)))
{
syslog(LOG_CRIT, "Creating Pcap-Reading Thread %d failed.",created);
printf( "Creating Pcap-Reading Thread %d failed.\n",created);
exit(1);
}
syslog(LOG_INFO, "Created Pcap-Reading Thread %d Successfully.",created);
created++;
}
Later I try to cancel them and restart them :
pthread_t t;
pthread_struct* tstr;
int i;
pthread_mutex_unlock( &mutex_threadsPool );
//first go on array and kill all threads
for(i = 0; i<threadsNum ; i++ ){
tstr = readingThreadsPool[i];
if (tstr!=NULL){
t = tstr->t;
if (pthread_cancel(t)!=0){
perror("ERROR : Could not kill thread");
}
else{
printf("Killed Thread %d \n",i);
}
}
}
So far so good, but the only problem is that the output is
Error : Could not kill thread : Illegal Seek
Killed Thread 1
Killed Thread 2
Killed Thread 3
Killed Thread 4
Killed Thread 5
Killed Thread 6
Killed Thread 7
Killed Thread 8
Killed Thread 9
Why doesn't it kill the thread in the 0 index as well?
And I couldn't find anything about Illegal Seek..
Thanks for your help people
Thanks
The problem is that newThread is being used before it is initialized:
pthread_t newThread;
pthread_struct *st;
st = (pthread_struct*)malloc(sizeof(pthread_struct));
st->id = created;
st->t = newThread;
but newThread does not receive a value until after the successful invocation of pthread_create(). It appears that newThread variable is retaining its previous value on subsequent iterations of the loop, which results in the correct cancelling of all threads except for last thread started as its id is never inserted into the readingThreadsPool array.
You need to populate the st->t member after the call to pthread_create().
As the code currently stands, it is possible for an entry to be inserted into the readingThreadsPool array even though it is not actually a thread yet. Put the insertion logic after the call to pthread_create():
if((threadRes1 =
pthread_create(&(st->t), NULL, pcapReadingThread, (void*)created)))
{
syslog(LOG_CRIT, "Creating Pcap-Reading Thread %d failed.",created);
printf( "Creating Pcap-Reading Thread %d failed.\n",created);
exit(1);
}
pthread_mutex_lock( &mutex_threadsPool );
readingThreadsPool[created] = st;
pthread_mutex_unlock( &mutex_threadsPool );
or if the pcapReadingThread() function accesses readingThreadsPool and expects an entry for itself (which I think might be the case due to created being passed) then enclose the pthread_create() inside the lock of mutex_threadsPool.
#include<pthread.h>
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define NUM_THREADS 8
char *messages[NUM_THREADS];
struct thread_data
{
int thread_id;
int sum;
char *message;
};
struct thread_data thread_data_array[NUM_THREADS];
void *PrintHello(void *threadarg)
{
int taskid, sum;
char *hello_msg;
struct thread_data *my_data;
sleep(1);
my_data = (struct thread_data *) threadarg;
taskid = my_data->thread_id;
sum = my_data->sum;
hello_msg = my_data->message;
printf("Thread %d: %s Sum=%d\n", taskid, hello_msg, sum);
pthread_exit(NULL);
}
int main(int argc, char *argv[])
{
pthread_t threads[NUM_THREADS];
//int *taskids[NUM_THREADS];
int rc, t, sum;
sum=0;
messages[0] = "English: Hello World!";
messages[1] = "French: Bonjour, le monde!";
messages[2] = "Spanish: Hola al mundo";
messages[3] = "Klingon: Nuq neH!";
messages[4] = "German: Guten Tag, Welt!";
messages[5] = "Russian: Zdravstvytye, mir!";
messages[6] = "Japan: Sekai e konnichiwa!";
messages[7] = "Latin: Orbis, te saluto!";
for(t=0;t<NUM_THREADS;t++) {
sum = sum + t;
thread_data_array[t].thread_id = t;
thread_data_array[t].sum = sum;
thread_data_array[t].message = messages[t];
printf("Creating thread %d\n", t);
rc = pthread_create(&threads[t], NULL, PrintHello, (void *)&thread_data_array[t]);
if (rc) {
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
}
pthread_exit(NULL);
}
The above piece of code gives me a segmentation fault in linux using gcc
As a beginner I have a few questions in mind regarding threads
If 3 threads are created simultaneously and if they have to exit then the thread that is created first is exitted at the end?
Can the o/p differ every time of a thread creation and termination program and if so why??(I have noticed they do so");
If 3 threads are created simultaneously and if they have to exit then the thread that is created first is exited at the end?
Answer: there is no guarantee that the first thread should exit first. Once they are created, they are treated as separate entities by the OS and it's up to the OS to decide which will exit first.
Can the o/p differ every time of a thread creation and termination program and if so why? (I have noticed they do so);
Answer: yes they do differ, the reason being the same as explained above.
How and when each thread is scheduled is completely upto the OS.
There is no way to understand this without digging deep into the OS code.
In most implementations of pthreads (I have not used all, but all I have used).
When the main thread exits all the other threads stop executing and the application quits.
Thus before exiting the main thread should wait for (or kill) all child threads before exiting.
For this we have pthread_join().
for(t=0;t<NUM_THREADS;t++)
{
void* result;
pthread_join(threads[t],&result);
}
// Now all the children are dead.
Note the underlying io system is not thread safe.
So if multiple threads write to IO then you may potentially get some interleaving.
Your code is working perfectely(I am also using gcc)..
output:
Creating thread 0
Creating thread 1
Creating thread 2
Creating thread 3
Creating thread 4
Creating thread 5
Creating thread 6
Creating thread 7
Thread 1: French: Bonjour, le monde! Sum=1
Thread 0: English: Hello World! Sum=0
Thread 2: Spanish: Hola al mundo Sum=3
Thread 4: German: Guten Tag, Welt! Sum=10
Thread 3: Klingon: Nuq neH! Sum=6
Thread 5: Russian: Zdravstvytye, mir! Sum=15
Thread 6: Japan: Sekai e konnichiwa! Sum=21
Thread 7: Latin: Orbis, te saluto! Sum=28