Oder wenn man in der reinen C Welt bleiben möchte - ist jetzt keine Kritik @Mxt - kann man's halt so machen:

Code:
#include <stdio.h>
#include <pthread.h>

struct PID {
  pthread_t tid;
  char* name;

  float p;
  float i;
  float d;
};

struct PID PID_A = {0, "Task A", 0.015, 0.2, 0.7 };
struct PID PID_B = {0, "Task B", 0.3, 0.5, 0.80 };

/* thread main */
void *pid_task(void *arg) {
  struct pid* PID = (struct pid*)arg;
  int idx = 0;

  for(idx = 0; idx < 8; idx++) {
    pid->p += .03;
    printf("[%d]: %s, p=%f, i=%f, d=%f\n", idx, pid->name, pid->p, 
	   pid->i, pid->d);
  }

  return 0;
}

int pid_start(struct pid* pid, float p, float i, float d, int flag) {
  pid->p = p;
  pid->i = i;
  pid->d = d;

  if(flag){
    ; /* Whatever */
  }

  return pthread_create(&pid->tid, 0, pid_task, pid);
}

int pid_stop(struct pid* pid, int cancel) {
  int rc = 0;

  if(cancel)
    pthread_cancel(pid->tid);

  rc = pthread_join(pid->tid, 0);
  pid->tid = 0;

  return rc;
}

int main(int argc, char** argv) {

  pid_start(&PID_A, .5, .3, .1, 0);
  pid_start(&PID_B, .2, 1.2, .3, 1);

  pid_stop(&PID_A, 0);
  pid_stop(&PID_B, 0);

  printf("Snd start:\n");

  pid_start(&PID_B, .2, 1.2, .3, 1);
  pid_start(&PID_A, .5, .3, .1, 0);

  pid_stop(&PID_A, 1);
  pid_stop(&PID_B, 0);
  return 0;
}