davenull
Posts: 1159
Joined: Thu Oct 22, 2015 7:22 am
Location: a small planet close to Betelgeuze

heya,

1) is a short tutorial available how to setup, how to use it and make a couple of tasks run simultaneously - and at the end clean all and everything?

ps,
I'm using g++ for C++ libs additionally

--------------------------------------
edit:
found something!
Last edited by davenull on Wed Nov 04, 2015 1:46 pm, edited 1 time in total.
#define S sqrt(t+2*i*i)<2
#define F(a,b) for(a=0;a<b;++a)
float x,y,r,i,s,j,t,n;int main(){F(y,64){F(x,99){r=i=t=0;s=x/33-2;j=y/32-1;F(n,50&S){t=r*r-i*i;i=2*r*i+j;r=t+s;}if(S){PointOut(x,y);}}}for(;;);}

davenull
Posts: 1159
Joined: Thu Oct 22, 2015 7:22 am
Location: a small planet close to Betelgeuze

### Re: pthread questions

2) is it useful to link by
-D_REENTRANT
additionally for Raspberry Pi?

3) how is it possible to immediately stop or kill 1 task by main() or by another task ?
(e.g.,
a) immediately in case of emergency stop (no cleaning required necessarily) or
b) by a higher-priority task (in this case a cleaning would be helpful )
#define S sqrt(t+2*i*i)<2
#define F(a,b) for(a=0;a<b;++a)
float x,y,r,i,s,j,t,n;int main(){F(y,64){F(x,99){r=i=t=0;s=x/33-2;j=y/32-1;F(n,50&S){t=r*r-i*i;i=2*r*i+j;r=t+s;}if(S){PointOut(x,y);}}}for(;;);}

stephj
Posts: 80
Joined: Thu Jun 21, 2012 1:20 pm
Location: Lancashire, UK

### Re: pthread questions

Have a read of Chapter 4: Threads
of the Advanced Linux Programming manual, which can be downloaded from here:

https://archive.org/details/ost-compute ... rogramming

Before you start ask yourself the following questions:

Can the task be broken down into multiple threads that can run totally independently of each other with their own separate resources and or memory areas? Not all tasks are suitable for this sort of thing.

It takes quite a lot of effort to design and write code that uses multiple threads, and sometimes it is just not worth it if you are not going to get a serious increase in program throughput, on a multi core processor.
Debugging it can be a nightmare, especially if you run into deadlock or race conditions, because the design was flawed at the start.

If you have to kill a thread off, your original design is probably suspect.

davenull
Posts: 1159
Joined: Thu Oct 22, 2015 7:22 am
Location: a small planet close to Betelgeuze

### Re: pthread questions

I'm already writing and using Multitasking programs since about 15 years, but not by C compilers but for different bytecode interpreters (sort of Java and this kind of stuff) which don't need compile parameters long enough to sink a ship - and I'm fine with killing tasks in case there's a need to do so.
#define S sqrt(t+2*i*i)<2
#define F(a,b) for(a=0;a<b;++a)
float x,y,r,i,s,j,t,n;int main(){F(y,64){F(x,99){r=i=t=0;s=x/33-2;j=y/32-1;F(n,50&S){t=r*r-i*i;i=2*r*i+j;r=t+s;}if(S){PointOut(x,y);}}}for(;;);}

davenull
Posts: 1159
Joined: Thu Oct 22, 2015 7:22 am
Location: a small planet close to Betelgeuze

### Re: pthread questions

update:

2) is it useful to link by
-D_REENTRANT
additionally for Raspberry Pi?

3) how is it possible to immediately stop or kill 1 task by main() or by another task ?
(e.g.,
a) immediately in case of emergency stop (no cleaning required necessarily) or
b) by a higher-priority task (in this case a cleaning would be helpful )

4) how is it possible for a pthread task to make it run at a 1-2 higher priority level?
How many priority levels are possible generally?

I currently have

and want to make thread1 run in a very simple way by a 1-2x higher priority than the rest.
#define S sqrt(t+2*i*i)<2
#define F(a,b) for(a=0;a<b;++a)
float x,y,r,i,s,j,t,n;int main(){F(y,64){F(x,99){r=i=t=0;s=x/33-2;j=y/32-1;F(n,50&S){t=r*r-i*i;i=2*r*i+j;r=t+s;}if(S){PointOut(x,y);}}}for(;;);}

joan
Posts: 15543
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

### Re: pthread questions

is probably a good place to start,

davenull
Posts: 1159
Joined: Thu Oct 22, 2015 7:22 am
Location: a small planet close to Betelgeuze

### Re: pthread questions

pls what?
could you pls just answer the 3 questions quick, short, and simple?
#define S sqrt(t+2*i*i)<2
#define F(a,b) for(a=0;a<b;++a)
float x,y,r,i,s,j,t,n;int main(){F(y,64){F(x,99){r=i=t=0;s=x/33-2;j=y/32-1;F(n,50&S){t=r*r-i*i;i=2*r*i+j;r=t+s;}if(S){PointOut(x,y);}}}for(;;);}

joan
Posts: 15543
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

### Re: pthread questions

davenull wrote:pls what?
could you pls just answer the 3 questions quick, short, and simple?
*nix documentation is in manual pages. man is the command to view the manual page for a topic.

If you want to know about a function then man function. If you want to know about a topic or configuration file then man topic or man configuration file will likely have some information.

davenull
Posts: 1159
Joined: Thu Oct 22, 2015 7:22 am
Location: a small planet close to Betelgeuze

### Re: pthread questions

no ideas by anyone?

I just needed the answers to the 3 questions (2-4), very quick, very short, and very simple, would this not be possible ?
2) is it useful to link by
-D_REENTRANT
additionally for Raspberry Pi?

3) how is it possible to immediately stop or kill 1 task by main() or by another task ?
(e.g.,
a) immediately in case of emergency stop (no cleaning required necessarily) or
b) by a higher-priority task (in this case a cleaning would be helpful )

4) how is it possible for a pthread task to make it run at a 1-2 higher priority level?
How many priority levels are possible generally?

I currently have

and want to make thread1 run in a very simple way by a 1-2x higher priority than the rest.
#define S sqrt(t+2*i*i)<2
#define F(a,b) for(a=0;a<b;++a)
float x,y,r,i,s,j,t,n;int main(){F(y,64){F(x,99){r=i=t=0;s=x/33-2;j=y/32-1;F(n,50&S){t=r*r-i*i;i=2*r*i+j;r=t+s;}if(S){PointOut(x,y);}}}for(;;);}

experix
Posts: 204
Joined: Mon Nov 10, 2014 7:39 pm
Location: Coquille OR
Contact: Website

### Re: pthread questions

The OP doesn't seem to have a solid grounding in thread usage, and his question comes across as a request for 1-on-1 tutoring, which probably isn't going to happen. The man pages are more helpful to people who already have some familiarity with the topic and need to review it and be reminded of details. For a great intro to thread usage and lots of examples, see the relevant chapters of The Linux Programming Interface by Michael Kerrisk.

davenull
Posts: 1159
Joined: Thu Oct 22, 2015 7:22 am
Location: a small planet close to Betelgeuze

### Re: pthread questions

thanks, but first I need quick answers to my 3 simple question, this could not be so hard, is it?
#define S sqrt(t+2*i*i)<2
#define F(a,b) for(a=0;a<b;++a)
float x,y,r,i,s,j,t,n;int main(){F(y,64){F(x,99){r=i=t=0;s=x/33-2;j=y/32-1;F(n,50&S){t=r*r-i*i;i=2*r*i+j;r=t+s;}if(S){PointOut(x,y);}}}for(;;);}

Paeryn
Posts: 3231
Joined: Wed Nov 23, 2011 1:10 am
Location: Sheffield, England

### Re: pthread questions

As long as you know that a "quick answer" to a "simple" question on multithreading isn't necessarily going to be he one you want. Reading up on pthreads (as suggested before) is a must. But if you want quick (I haven't done multithreaded programming on *nix for a long time so this may be out of date or I may be remembering wrongly, plus some googling filled in bits) :-

You should really use -pthread rather than -lpthread as as well as including the library it also sets any other options (which usually on linux means setting -D_REENTRANT as well). So yes, if you use -lpthread then you need -D_REENTRANT otherwise things could go wrong.

You can ask a thread to cancel with pthread_cancel(threadID); It should then stop at the next cancel point. I think threads default to delayed cancelling, though a thread can set it's cancel type to asynchronous (will be cancelled without waiting for a cancel point) with pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &previousCancelType);. You'll need to make sure the thread (and/or parent thread) knows how to clean up properly.

You can request changing priority with pthread_setschedprio(threadID, priority); Exactly what values to use for priority depends on the scheduling policy.
She who travels light — forgot something.
Please note that my name doesn't start with the @ character so can people please stop writing it as if it does!

davenull
Posts: 1159
Joined: Thu Oct 22, 2015 7:22 am
Location: a small planet close to Betelgeuze

### Re: pthread questions

The other references are more complicated than I expected them to be but at least give me a guidance to keywords I have to look at more closely, maybe I will then see more clear. Finally for me as a former programmer for bytecode to VMs (edit, and for Arduinos) it's not just about missing (overcomplicated, messed up) Linux detailes but also simple missing English language knowledge (where Goggle translate is additionally messing all things up).
VMs (edit, and the Arduinos IDE) always finally were handling all the complicated underlaying stuff so I could focus on my own algorithms, now I have to rewrite the whole operating system before, as it seems.

e.g., for the first elementary step into this maze: what is threadID ?

So far I just have

which of these items is the thread ID I have to pass to pthread_cancel ?
Last edited by davenull on Sun Nov 08, 2015 9:01 am, edited 1 time in total.
#define S sqrt(t+2*i*i)<2
#define F(a,b) for(a=0;a<b;++a)
float x,y,r,i,s,j,t,n;int main(){F(y,64){F(x,99){r=i=t=0;s=x/33-2;j=y/32-1;F(n,50&S){t=r*r-i*i;i=2*r*i+j;r=t+s;}if(S){PointOut(x,y);}}}for(;;);}

AndyD
Posts: 2334
Joined: Sat Jan 21, 2012 8:13 am
Location: Melbourne, Australia
Contact: Website

### Re: pthread questions

Code: Select all

``int pthread_cancel(pthread_t thread);``

davenull
Posts: 1159
Joined: Thu Oct 22, 2015 7:22 am
Location: a small planet close to Betelgeuze

### Re: pthread questions

excellent, now I can start working with this information!

many thanks, Andy, and again, also to Paeryn!
#define S sqrt(t+2*i*i)<2
#define F(a,b) for(a=0;a<b;++a)
float x,y,r,i,s,j,t,n;int main(){F(y,64){F(x,99){r=i=t=0;s=x/33-2;j=y/32-1;F(n,50&S){t=r*r-i*i;i=2*r*i+j;r=t+s;}if(S){PointOut(x,y);}}}for(;;);}

davenull
Posts: 1159
Joined: Thu Oct 22, 2015 7:22 am
Location: a small planet close to Betelgeuze

### Re: pthread questions

hey,

I'm trying to handle pthread now for higher priority tasks.
Given I have a program starting 3 pthread tasks, and the first one should run continuously by a higher priority than all the others to be capable of a better "real-time" performance, I now am starting with this code:

Code: Select all

``````#include <stdio.h>
#include <wiringPi.h>
//...

{
while(1) {
///... (code/loop)
delayMicroseconds(100);
}
return NULL;
}

{
while(1) {
///... (code/loop)
delay(10);
}
return NULL;
}

{
while(1) {
///... (code/loop)
delay(1);
}
return NULL;
}

int priority=1;            // <<<<<<<<<<<< ??? which value for high priority ? 1? 2? 3?...?

//wait for threads to join before exiting

return 0;
}

``````

Task1 should become a higher priority, as I need to mimic a quite (!) reliable 100µs loop time performance to poll GPIO pins repetitively, both against internal pthread tasks and as well against possibly most all other currently running user space tasks/demons/whatever.

As I am a complete beginner to pthread, my questions are:
- is my approach correct?
- at which priority level are tasks running by default?
- which value for priority should a choose for task1?
- is there anything else to add to the code?

I'm running this code on a Raspi 2B.
#define S sqrt(t+2*i*i)<2
#define F(a,b) for(a=0;a<b;++a)
float x,y,r,i,s,j,t,n;int main(){F(y,64){F(x,99){r=i=t=0;s=x/33-2;j=y/32-1;F(n,50&S){t=r*r-i*i;i=2*r*i+j;r=t+s;}if(S){PointOut(x,y);}}}for(;;);}

AndyD
Posts: 2334
Joined: Sat Jan 21, 2012 8:13 am
Location: Melbourne, Australia
Contact: Website

### Re: pthread questions

davenull
Posts: 1159
Joined: Thu Oct 22, 2015 7:22 am
Location: a small planet close to Betelgeuze

### Re: pthread questions

thank you, I already read this, I have googled all and everything I could finde - but everything I read is far too sophisticated and I understand not a single word ( also attributable to by poor English skills).
So I need just 1 practical source code about my code above and how to make it correct (anyway, I'm not sure that it will work even on the quadacore in order to achieve a better real-time capability though) -
Task1 should become a higher priority, as I need to mimic a quite (!) reliable 100µs loop time performance to poll GPIO pins repetitively, both against internal pthread tasks and as well against possibly most all other currently running user space tasks/demons/whatever.

As I am a complete beginner to pthread, my questions are:
- is my approach correct?
- at which priority level are tasks running by default?
- which value for priority should a choose for task1?
- is there anything else to add to the code?
#define S sqrt(t+2*i*i)<2
#define F(a,b) for(a=0;a<b;++a)
float x,y,r,i,s,j,t,n;int main(){F(y,64){F(x,99){r=i=t=0;s=x/33-2;j=y/32-1;F(n,50&S){t=r*r-i*i;i=2*r*i+j;r=t+s;}if(S){PointOut(x,y);}}}for(;;);}

AndyD
Posts: 2334
Joined: Sat Jan 21, 2012 8:13 am
Location: Melbourne, Australia
Contact: Website

### Re: pthread questions

I think the answer is, that it is complicated. If I am reading the output of "chrt -m" correctly, it would appear that you can only change a threads priority if you set the scheduling policy to either SCHED_FIFO or SCHED_RR. Otherwise the minimum and maximum priorities are zero.

Code: Select all

``````% chrt -m
SCHED_OTHER min/max priority    : 0/0
SCHED_FIFO min/max priority     : 1/99
SCHED_RR min/max priority       : 1/99
SCHED_BATCH min/max priority    : 0/0
SCHED_IDLE min/max priority     : 0/0``````

davenull
Posts: 1159
Joined: Thu Oct 22, 2015 7:22 am
Location: a small planet close to Betelgeuze

### Re: pthread questions

IIRC, Gordon Henderson was doing a similar thing to his WiringPi libs, by running the thread to poll GPIOs by a higher priority task.
But I don't only have to poll pins quickly, I also have to process them even as quickly as possible, instantaneously, without delay.

As I'm completely new to Linux and pthread, but common user space tasks are definitvely too slow and too untrustworthy, and because the Raspi does not provide hardware-timer-Interrupts- what should I do best?
I have no idea about scheduling policies, but I am afraid it would not be as easy to do as by OSEK RTOS where one can simply specify task priorities in the related .oil files.
So Linux is really a torture if one needs quick real-time capabilities by reliable 100µs clock beats.

Anyway, as I am not able to figure that out:

Who is experienced in higher priority threading, establishing:

a 100µs thread (+/- 30%),
don't yield,
to poll (at least) 8 GPIOs (for rotary encoders) safely,
still don't yield,
acquire a mutex,
still don't yield,
process the 8 values to calculate the curent encoder position upadtes of (at least) 4 rotary encoders,
don't yield in between,
when finished:
release that mutex,
and only when processed everything and when completely finished
- then yield to the next time slice.

But during the round-robin:
safely re-awaken when another 100µs have passed,
when necessary force the current timeslice to yield prematurely,
in order to do the next high priority processing loop.

This is actually what an Arduino Due does when a ARM DueTimer Interrupt has been established (or even AVRs by AVR Timer Interrupts).
#define S sqrt(t+2*i*i)<2
#define F(a,b) for(a=0;a<b;++a)
float x,y,r,i,s,j,t,n;int main(){F(y,64){F(x,99){r=i=t=0;s=x/33-2;j=y/32-1;F(n,50&S){t=r*r-i*i;i=2*r*i+j;r=t+s;}if(S){PointOut(x,y);}}}for(;;);}

AndyD
Posts: 2334
Joined: Sat Jan 21, 2012 8:13 am
Location: Melbourne, Australia
Contact: Website

### Re: pthread questions

Gordon basically uses the following:

Code: Select all

``````struct sched_param param;

param.sched_priority = sched_get_priority_max(SCHED_RR);
within a thread. This sets the scheduling policy to Round Robin and sets the priority of the thread to the maximum priority for the Round Robin policy.

In your example ...

Code: Select all

``````struct sched_param param;

param.sched_priority = sched_get_priority_max(SCHED_RR);

davenull
Posts: 1159
Joined: Thu Oct 22, 2015 7:22 am
Location: a small planet close to Betelgeuze

### Re: pthread questions

that looks very promising , thank you Andy!

Just 1 thing:
where have I to put these lines exactly?
or In task main() immediatly after declaring thread1Name(),
or (most unlikely, but who knows) -: inside / alt the start of the task thread1Name() itself, perhaps before the endless loops is started?

and then the rest of the declarations and implementations for the remaining tasks can be kept as it is?

Code: Select all

``````#include <stdio.h>
#include <wiringPi.h>
//...

{
while(1) {
///... (code/loop)
delayMicroseconds(100);
}
return NULL;
}

{
while(1) {
///... (code/loop)
delay(10);
}
return NULL;
}

{
while(1) {
///... (code/loop)
delay(1);
}
return NULL;
}

// declare the threads

//wait for threads to join before exiting

return 0;
}
``````
#define S sqrt(t+2*i*i)<2
#define F(a,b) for(a=0;a<b;++a)
float x,y,r,i,s,j,t,n;int main(){F(y,64){F(x,99){r=i=t=0;s=x/33-2;j=y/32-1;F(n,50&S){t=r*r-i*i;i=2*r*i+j;r=t+s;}if(S){PointOut(x,y);}}}for(;;);}

jojopi
Posts: 3425
Joined: Tue Oct 11, 2011 8:38 pm

### Re: pthread questions

davenull wrote:So Linux is really a torture if one needs quick real-time capabilities by reliable 100µs clock beats.
Yes. If you want your thread to wake up every 100µs, then that does not leave enough time asleep for the kernel to reprogram the memory management unit and schedule another task for long enough to do anything useful. The real time thread is going to hog an entire core, so you had better be using a Pi2.

To get 20000 context switches per second you would need a real time operating system with simpler memory protection, or better still, use interrupts. The Pi does have programmable timer interrupts (I do not know how fast they go) and GPIO change interrupts. But interrupts need to be handled in kernel memory, and kernel internals are sparsely documented, so writing a kernel module is not a good option for you.
But I don't only have to poll pins quickly, I also have to process them even as quickly as possible, instantaneously, without delay.
What are you actually doing with the rotary encoder positions, once you have calculated them? If you did not need such low latency then a better option might be to sample the GPIOs continuously using the DMA engine via pigpio, and process the data in chunks.

davenull
Posts: 1159
Joined: Thu Oct 22, 2015 7:22 am
Location: a small planet close to Betelgeuze

### Re: pthread questions

1st, Im using the Pi 2B quadcore - for a single core it's perhaps even more unsolvable.
2nd, I'm using the encoders for odometry of an autonomous vehicle/robot, and for PID controls of a robot arm control (move to encoder target, start and brake smoothly, don't stall close to the target, don't overshoot).
So once the pin signal edges (2x2=4 pin changes up/down) have been detected and the encoder values have been counted and added/subtracted correctly without dropping counts (at every ~100- up to 200µs), then the evaluation for odometry and PID control is working fine at 1-2ms tasks - provided that the encoder value has been processed correctly before.

Till now I tried 2 options which did NOT work:
- Gordon Henderson provided a code example using WiringPi for 1 single pinchange event (just 1 pin of 2 at pin_up), but by that I only get 1/4 resolution, that's too poor.
- Using all 4 pinchanges instead for pinchange interrupts (pin A up/dn, pin B up/down) and that for all 4 rotary encoders it calls this routine far too often and so it drops repetitively 1/5 of all encoder ticks (getting just 300 ticks for 360 degrees instead of, you might have guessed it: 360 ticks).
So pinchange IRQs for 4x4=16 pinchange events is not a good choice.

Instead, Timer IRQs at 100µs (+/-) are fine: enough time to make sort of a "flash-light foto" of all 16 pinstates and then calculating the changes by current pin levels!
That works fine on all my Arduinos, not just AVRs but also my ARMs (Due, and even Zero).
The code is very common and works on my Arduinos even for 8 motors = 32 pinchange edges: on a Arduino Mega in 200µs loops.
This is the ISR task (taken from my Arduino Due code controlling 6 motors):

Code: Select all

``````/*************************************************************
* Interrupt Handler Routine
*************************************************************/

void encHandler() {

ISRab [ 0] <<= 2;
ISRab [ 0] &= B00001100;
ISRab [ 0] |= (digitalRead(pinenc0A) << 1) | digitalRead(pinenc0B);
motenc[ 0] += schrittTab[ISRab[0]];           //

ISRab [ 1] <<= 2;
ISRab [ 1] &= B00001100;
ISRab [ 1] |= (digitalRead(pinenc1A) << 1) | digitalRead(pinenc1B);
motenc[ 1] += schrittTab[ISRab[1]];           //

ISRab [ 2] <<= 2;
ISRab [ 2] &= B00001100;
ISRab [ 2] |= (digitalRead(pinenc2A) << 1) | digitalRead(pinenc2B);
motenc[ 2] += schrittTab[ISRab[2]];           //

ISRab [ 3] <<= 2;
ISRab [ 3] &= B00001100;
ISRab [ 3] |= (digitalRead(pinenc3A) << 1) | digitalRead(pinenc3B);
motenc[ 3] += schrittTab[ISRab[3]];           //

ISRab [ 4] <<= 2;
ISRab [ 4] &= B00001100;
ISRab [ 4] |= (digitalRead(pinenc4A) << 1) | digitalRead(pinenc4B);
motenc[ 4] += schrittTab[ISRab[4]];           //

ISRab [ 5] <<= 2;
ISRab [ 5] &= B00001100;
ISRab [ 5] |= (digitalRead(pinenc5A) << 1) | digitalRead(pinenc5B);
motenc[ 5] += schrittTab[ISRab[5]];           //

}

``````
Last edited by davenull on Mon Jan 04, 2016 2:30 pm, edited 1 time in total.
#define S sqrt(t+2*i*i)<2
#define F(a,b) for(a=0;a<b;++a)
float x,y,r,i,s,j,t,n;int main(){F(y,64){F(x,99){r=i=t=0;s=x/33-2;j=y/32-1;F(n,50&S){t=r*r-i*i;i=2*r*i+j;r=t+s;}if(S){PointOut(x,y);}}}for(;;);}

davenull
Posts: 1159
Joined: Thu Oct 22, 2015 7:22 am
Location: a small planet close to Betelgeuze

### Re: pthread questions

but I would prefer to try Andy's suggestion now, so just for my understanding:
davenull wrote:
AndyD wrote:In your example ...

Code: Select all

``````    struct sched_param param;

param.sched_priority = sched_get_priority_max(SCHED_RR);
that looks very promising , thank you Andy!

Just 1 thing:
where have I to put these lines exactly?
or In task main() immediatly after declaring thread1Name(),
or (most unlikely, but who knows) -: inside / at the start of the task thread1Name() itself, perhaps before the endless loop is started?

and then the rest of the declarations and implementations for the remaining tasks can be kept as it is?

Code: Select all

``````#include <stdio.h>
#include <wiringPi.h>
//...

{
while(1) {
///... (code/loop)
delayMicroseconds(100);
}
return NULL;
}

{
while(1) {
///... (code/loop)
delay(10);
}
return NULL;
}

{
while(1) {
///... (code/loop)
delay(1);
}
return NULL;
}

// declare the threads

//wait for threads to join before exiting