Problem with signals/select with pthreads (linux)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello,

i have quite a problem with pthreads (linux 2.4.22).
Scenario:
My process creates a thread using pthread_create().
Thread A is the one communicating with the network (using select() ),
Thread B does some work for Thread A.

Now i need the following:
- Thread A must be able to wake Thread B when there's some work to do.
  I'm doing this via pthread_kill() and sigwait(). This works just fine.
- Thread B must be able to wake Thread A from its select() call,
  so Thread A can accept the data that has been processed by Thread B.
  And this does _not_ work.

I have even tried not using signals but using select() in both threads
and a "fake pipe" for them to be able to wake each other from their
select() calls, but this does not work either.

My code looks about as follows (error checks removed):

        pthread_create(&worker_tid, (pthread_attr_t *)NULL,
                  (void *)worker_thread, NULL);
        consumer_thread();

void worker_thread() {
        sleep_2_seconds();
        printf("worker: waking consumer\n");
        wake_consumer();
        printf("worker: woke consumer\n");
}

void consumer_thread() {
        init_consumer_signals();
        ..
        timeout.tv_sec = 3;
        timeout.tv_usec = 0;
        ..
        printf("consumer going to sleep!\n");
        ret = select(maxfd+1, &rfd, &wfd, 0, &timeout);
        printf("consumer thread just woke up!\n");
        ..
}

void init_consumer_signals() {
        struct sigaction action;
        sigset_t set;
        sigemptyset(&action.sa_mask);
        action.sa_flags = SA_RESTART;
                /* also does not work without SA_RESTART */
        action.sa_handler = consumer_setflag;
                /* neither select() returns, nor is this signal
                 * handler executed..!
                 */
        sigaction(SIGUSR1, &action, NULL);
        sigemptyset(&set);
        sigaddset(&set, SIGUSR1);
        pthread_sigmask(SIG_UNBLOCK, &set, NULL);
}

void wake_consumer() {
        pid_t pid;
        pid = getpid();
        /* have also tried pthread_kill with a cast, did not work.
         * where do i get the pthread_t of the consumer from? dp
         * i readlly need to create _another_ thread, leaving the
         * creating thread just idle, just to get a thread id?
         */
        kill(pid, SIGUSR1);
}


Help/suggestions appreciated.
Maybe some of you know some open source applications that use pthreads and 
a similar communication model, if so please tell me about them so i can
take a look at the code. In case there's a much more elegant way to do
this, i'd be interested in hearing about it.
Thanks for your help and contribution!

Greetings
 Marc Roessler

-
: send the line "unsubscribe linux-net" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Netdev]     [Ethernet Bridging]     [Linux 802.1Q VLAN]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Git]     [Bugtraq]     [Yosemite News and Information]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux PCI]     [Linux Admin]     [Samba]

  Powered by Linux