0

Hello,

I'm using pause() to suspend threads until I need them and pthread_kill(thread, SIGCONT) to resume. It works the first time over with the thread unpausing the first time I send SIGCONT, but not the second time around. Does sending the signal cause it to be ignored and if so, how do I reset it?

Thanks

2
Contributors
9
Replies
11
Views
4 Years
Discussion Span
Last Post by histrungalot
0

So blocking is looking really ugly for something that should easily be done with signals, any clue why sending sigcont the second time around cause trouble?

0

Can you post some code that I can run to reproduce you error? Otherwise I can fabricate something.

Edited by histrungalot: n/a

0

Can you post some code that I can run to reproduce you error? Otherwise I can fabricate something.

when child thread completes:
pause();

when main thread needs child to repeat routine (child thread is inf. loop):
pthread_kill(mThreadList, SIGCONT);

The main thread looks at an array of bool to see if all the child threads completed and before sending SIGCONT, I set all of them to false. Since neither assign values to the array at the same time, I didn't bother with blocking.

Since there's a lot going on in my code, writing a simple test case would be best.

Edited by Mr.UNOwen: n/a

1

This is working for me.

#include <pthread.h>
#include <stdio.h>
#include <signal.h>
#include <string.h>
#include <unistd.h>

#define NUM_THREADS 2
pthread_t tid[NUM_THREADS];

void handler(int signum){
  // Empty
}
void *thrFunc(void *arg){
  long long id=(long long)arg;
  while(1) {
     printf("Pausing thread(%lld)\n",id);
     pause();
     printf("Working thread(%lld)\n",id);
  } 
  pthread_exit(0);
}

int main(){
  long long i;
  int err, id;
  char line[1024];
  struct sigaction act;
  act.sa_handler = handler;
  sigemptyset(&act.sa_mask);
  act.sa_flags = 0;
  // Register signal and signal handler
  sigaction(SIGCONT, &act, NULL);
  for ( i=0; i < NUM_THREADS; i++) {
      err = pthread_create(&tid[i], NULL, thrFunc, (void *)(i+1));
      if (err != 0)
         printf("Error creating thread(%lld)\n",i);
  }
  do {
    sleep(1);
    printf("Enter thread to wake [1-%d]: ",NUM_THREADS);
    if (!fgets(line,sizeof(line),stdin)) 
        break;
    i = atoll(line);
    if ( i <= 0 || i > NUM_THREADS) 
      continue;
    printf("Waiting up thread(%lld)\n",--i);
    err = pthread_kill(tid[i],SIGCONT);
    if ( err ) {
       printf("Error: %s\n",strerror(err));
    }
  } while(1);
  printf("\nKilling\n");
  for ( i=0; i < NUM_THREADS; i++) {
      err = pthread_cancel(tid[i]);
      err = pthread_join(tid[i], NULL);
      if (err != 0)
         printf("Error joining thread(%lld)\n",i);
  }
  return 0;
}

Output:

$ gcc sigs.c -lpthread
$ ./a.out
Pausing thread(1)
Pausing thread(2)
Enter thread to wake [1-2]: 1
Waiting up thread(0)
Working thread(1)
Pausing thread(1)
Enter thread to wake [1-2]: 2
Waiting up thread(1)
Working thread(2)
Pausing thread(2)
Enter thread to wake [1-2]: 2
Waiting up thread(1)
Working thread(2)
Pausing thread(2)
Enter thread to wake [1-2]: 1
Waiting up thread(0)
Working thread(1)
Pausing thread(1)
Enter thread to wake [1-2]: ^D
Killing
$
0

This is working for me.

#include <pthread.h>
#include <stdio.h>
#include <signal.h>
#include <string.h>
#include <unistd.h>

#define NUM_THREADS 2
pthread_t tid[NUM_THREADS];

void handler(int signum){
  // Empty
}
void *thrFunc(void *arg){
  long long id=(long long)arg;
  while(1) {
     printf("Pausing thread(%lld)\n",id);
     pause();
     printf("Working thread(%lld)\n",id);
  } 
  pthread_exit(0);
}

int main(){
  long long i;
  int err, id;
  char line[1024];
  struct sigaction act;
  act.sa_handler = handler;
  sigemptyset(&act.sa_mask);
  act.sa_flags = 0;
  // Register signal and signal handler
  sigaction(SIGCONT, &act, NULL);
  for ( i=0; i < NUM_THREADS; i++) {
      err = pthread_create(&tid[i], NULL, thrFunc, (void *)(i+1));
      if (err != 0)
         printf("Error creating thread(%lld)\n",i);
  }
  do {
    sleep(1);
    printf("Enter thread to wake [1-%d]: ",NUM_THREADS);
    if (!fgets(line,sizeof(line),stdin)) 
        break;
    i = atoll(line);
    if ( i <= 0 || i > NUM_THREADS) 
      continue;
    printf("Waiting up thread(%lld)\n",--i);
    err = pthread_kill(tid[i],SIGCONT);
    if ( err ) {
       printf("Error: %s\n",strerror(err));
    }
  } while(1);
  printf("\nKilling\n");
  for ( i=0; i < NUM_THREADS; i++) {
      err = pthread_cancel(tid[i]);
      err = pthread_join(tid[i], NULL);
      if (err != 0)
         printf("Error joining thread(%lld)\n",i);
  }
  return 0;
}

Output:

$ gcc sigs.c -lpthread
$ ./a.out
Pausing thread(1)
Pausing thread(2)
Enter thread to wake [1-2]: 1
Waiting up thread(0)
Working thread(1)
Pausing thread(1)
Enter thread to wake [1-2]: 2
Waiting up thread(1)
Working thread(2)
Pausing thread(2)
Enter thread to wake [1-2]: 2
Waiting up thread(1)
Working thread(2)
Pausing thread(2)
Enter thread to wake [1-2]: 1
Waiting up thread(0)
Working thread(1)
Pausing thread(1)
Enter thread to wake [1-2]: ^D
Killing
$

Thanks, now it's going a few 100 rounds before I start seeing each thread halt. I'm writing a program that has each thread calculating a chunk of a wave, so now I see squares of it halting while others are still going, plus they're out of sync.

Adding sigaction did the job, which is odd since I thought changing the mask would be enough.

0

Thanks, now it's going a few 100 rounds before I start seeing each thread halt. I'm writing a program that has each thread calculating a chunk of a wave, so now I see squares of it halting while others are still going, plus they're out of sync.

Adding sigaction did the job, which is odd since I thought changing the mask would be enough.

Found the bug, totally unrelated to this problem... yay it work.

0

Good. I wasn't sure if you were still working the issue from you last last post. Just for reference I looked at some tool that we use and how they block/sleep theads, it uses semaphores (sem_wait and sem_post).

This article has been dead for over six months. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.