How to sleep and wake a thread???

Hi guys,
I am creating two posix threads. I have some queries, hopefully you will help me out with them
1) How can I put a thread to indefinite sleep, for indefinite time period. I am familiar with this

sleep(5);

for 5 second, how can I make it indefinite??
2) How can one thread wake another sleeping thread
3) Can one thread force another thread to go to sleep

Here is the program which is really bothering me, the idea is to have two threads, one filling the stack, and one emptying it. But I can't have one of my thread to wake up the other, after the stack is empty or full
See it for yourself!

 
#include <stdio.h>
#include <stdlib.h>
#include <curses.h>
#include <sys/types.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>
#define MAX_SIZE 10
int Counter;
struct Stack
{
 int home[MAX_SIZE];
 int top;
};
struct Stack s;
void InitStack(struct Stack *s)
{
 s->top = -1;
 Counter = 0;
}
void Push(struct Stack *s, int x)
{
 if(s->top == MAX_SIZE-1)
 {
  printf("Stack is full!\n");
  exit(0);
 }
 else
 s->top++;
 s->home[s->top] = x;
 Counter++;
 printf("Counter = %d\n", Counter);
}
void Pop(struct Stack *s)
{
 int y;
 if(s->top == -1)
 {
  printf("Stack empty!\n");
  exit(0);
 }
 else
 y = s->home[s->top];
 s->top--;
 printf("%d poped\n",y);
 Counter--;
 printf("Counter = %d\n", Counter);
}

void *threadA(void *);
void *threadB(void *);
int main()
{
 InitStack(&s); 
 int i, j, k;
 pthread_t tid[2];
 pthread_attr_t attr[2];
 for(i=1;i<=2;i++)
 {
  pthread_attr_init(&attr[i-1]);
 }
  {
  pthread_create(&tid[0],&attr[0],threadA,(void *)786);
  pthread_create(&tid[1],&attr[1],threadB,(void *)786);
  }
 { 
 pthread_join(tid[0],NULL);
 pthread_join(tid[1],NULL);
 }
return 0;
}

void *threadA(void *n)
{
 int x;
 x = (int)n;
 while(1) 
 {
 if(Counter != MAX_SIZE)
 {
 Push(&s,x);
 printf("x = %d\n", x);
 sleep(1);
 }
 else
 {
 printf("Going for a long sleep as Stack is full!\n");
 sleep(50);
 }
 }
}
void *threadB(void *n)
{
 int x;
 sleep(15);
 while(1)
 {
 if(Counter != 0)
 {
 Pop(&s);
 sleep(1);
 }
 else
 {
 printf("Going for a long sleep as Stack is empty!\n");
 sleep(50);
 }
 }
}

If you can explain your points with a very small program, that would be so so nice of you.
Desperately waiting for your wonderful replies!!!!

Thanks alot in advance!

You can sleep "indefinitely" with the pause() function, defined in <unistd.h>, which will sleep until you receive a signal.

You can wake a pause()d thread with pthread_kill() to send some signal that won't kill it (SIGCONT seems appropriate).

Though if you're expecting threads to cooperate, you should look into conditions and mutexes.

As John said above, you probably want your thread to block not sleep. Calls like sleep send SIGALRM to the calling process, not just the thread. This means that you have to set up signal handling for the thread in question, and have all the other threads ignore
SIGALRM (example only, there are other signals)

Using a condition wait or a mutex wait is much more efficient.

Looks like you have a typical synchronization problem. One such you would like to use conditional variables to solve. Have a look at pthread_cond_wait, pthread_cond_signal, mutexes and related stuff.

Could you please write a small little program to show how these functions work, I beg you please!
Thanks!

Try googling for examples.

Oh, and:

Not by any mechanism that I know of.

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

// Simplest way to create a mutex, no function calls needed
pthread_mutex_t lock=PTHREAD_MUTEX_INITIALIZER;

// When two threads must use the same memory, you must use
// mutex calls to make it safe.  It's not just a lock, it's also a
// "memory barrier", guaranteeing memory values between different CPU cores
// are synchronized properly.
int running=1;

void *thread(void *arg)
{
        fprintf(stderr, "Thread beginning\n");
        while(1)
        {
                int r;
                fprintf(stderr, "thread waiting for lock\n");
                // If main already has the mutex, thread will sleep.
                // when main unlocks it, the thread will lock it and continue.
                pthread_mutex_lock(&lock);
                        fprintf(stderr, "We have the mutex, it is safe to get value of 'running'\n");
                        r=running;
                        fprintf(stderr, "Value of 'running' is %d\n", r);
                pthread_mutex_unlock(&lock); // What gets locked MUST be unlocked later!
                fprintf(stderr, "thread has given up the lock\n");
                if(r == 0) break;
                sleep(1);
        }
        fprintf(stderr, "thread finishing\n");

        return((void *)0xdeadbeef);
}

int main()
{
        void *ret;
        pthread_t tid;
        running=1;
        pthread_mutex_lock(&lock); // Stop thread from getting the mutex
        fprintf(stderr, "main now has the mutex\n");

        pthread_create(&tid, NULL, thread, NULL);
        sleep(2); // Thread will begin, but wait for mutex

        fprintf(stderr, "main is unlocking the mutex\n");
        pthread_mutex_unlock(&lock); // Let the thread run for a while
        sleep(5);

        // Lock the mutex, making it safe to alter 'running'
        pthread_mutex_lock(&lock);
                fprintf(stderr, "main now has the mutex\n");
                running=0;
                fprintf(stderr, "main is unlocking the mutex\n");
        pthread_mutex_unlock(&lock);

        pthread_join(tid, &ret);
        fprintf(stderr, "Thread finished with return value %p\n", ret);
}

sleep doesn't send SIGALRM.

At any rate, pause will work, I've seen people do:

for ( ; ; ) sleep(UINT_MAX);

And then, as mentioned, pthread_kill can wake it provided the thread hasn't blocked the signal.

Also, as mentioned, there is no way for another thread to cause someone to "go to sleep".

For your edification, this seems like a simple producer-consumer model, and that's usually handled with condition variables. See: pthread_cond_init, pthread_cond_wait, and pthread_cond_signal.

Interesting. That'll take some careful use of signals though, whether a system call returns with SIGINT when interrupted is optional, and not all systems have the same default.

Maybe not on your system, but some sure do.

That's why you use sigaction; if you want the system call to restart after signal then supply the SA_RESTART flag, otherwise, don't and you'll get SIGINT. While the default behavior may be different across systems, sigaction insures you get the behavior you want. This is why sigaction is preferred over signal for portable code.

edit: as an aside, when we ported a large system from HP-UX to Linux this was a big problem. The team doing the port didn't understand signals very well in general, and the default behavior of a handler installed with signal in HP-UX is different from Linux. They had lots of issues, and I had to explain quite a bit to them to get things working right. Linux was also a lot less forgiving of their dumb use of sigblock and sigunblock to "protect" them from reentering a signal handler. This stupidity caused some very interesting stack traces until I explained the right way to do it was to provide the correct signal mask to sigaction so the block/unblock would occur atomically with the calling of the signal.... Ahh...good times with less than stellar developers, lol.

I suppose the man page for sleep does mention SIGALRM may be used to implement sleep, but have you seen one actually do it?

Probably old systems and maybe not so old systems, but with old implementations of the sleep library function. I think we had better do not make any assumptions on whether the sleep function will raise the SIGALRM signal or not, at least when portability is important.

I wouldn't be surprised. There's some you still need to use K&R C in.