LinuxQuestions.org
Help answer threads with 0 replies.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 03-06-2015, 06:18 AM   #1
sisrnb
LQ Newbie
 
Registered: Dec 2013
Distribution: debian wheezy
Posts: 23

Rep: Reputation: Disabled
Question Failed to make error EINTR with pthread_kill, but succeed with kill


To do unit test, I want to make sem_wait get error EINTR.
I've written a program below:
Code:
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <errno.h>

#define PRINTF(fmt, ...)   printf("%s:%d: " fmt, __FUNCTION__, __LINE__, ## __VA_ARGS__)
#define WAIT_INTERVAL      1000

static sem_t sem;

static void sig_handler_drp(int sig)
{
   if (SIGUSR1 == sig)
   {
      PRINTF("SIGUSR1 received\n");
   }
}
void *thread_drp(void *arg)
{
   usleep(WAIT_INTERVAL);
   if (kill(getpid(), SIGUSR1))
   {
      PRINTF("ERROR! kill\n");
   }
//   if (pthread_kill(*(pthread_t *)arg, SIGUSR1))
//   {
//      PRINTF("ERROR! pthread_kill\n");
//   }
   return NULL;
}
int main(int argc, char ** argv)
{
   struct sigaction sa;
   pthread_t tid;

   memset(&sa, 0, sizeof(struct sigaction));
   sa.sa_handler = sig_handler_drp;
   sigemptyset(&sa.sa_mask);
   sa.sa_flags = 0;
   if (-1 == sigaction(SIGUSR1, &sa, NULL))
   {
      PRINTF("ERROR! sigaction\n");
   }
   if (sem_init(&sem, 0, 0))
   {
      PRINTF("ERROR! sem_init\n");
   }
   if (pthread_create(&tid, NULL, thread_drp, &tid))
   {
      PRINTF("ERROR! pthread_create\n");
   }

   if (sem_wait(&sem))
   {
      PRINTF("ERROR! sem_wait\n");
      if (EINTR == errno)
      {
         PRINTF("ERROR! sem_wait gets EINTR\n");
      }
   }

   if (pthread_join(tid, NULL))
   {
      PRINTF("ERROR! pthread_join\n");
   }
   if (sem_destroy(&sem))
   {
      PRINTF("ERROR! sem_destroy\n");
   }

   return 0;
}
The output of the program is:
Code:
sig_handler_drp:19: SIGUSR1 received
main:59: ERROR! sem_wait
main:62: ERROR! sem_wait gets EINTR
If I use pthread_kill instead of kill in function thread_drp,
the program will get stuck by sem_wait.
Why I can't make error EINTR with pthread_kill?
 
Old 03-06-2015, 08:04 AM   #2
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,874
Blog Entries: 1

Rep: Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871
Why did you expect you could?

Anyways, change this:

Code:
old:  PRINTF("ERROR! sem_wait\n");
new:  PRINTF("ERROR! sem_wait errno=d: %s\n", errno, strerror (errno));

Last edited by NevemTeve; 03-06-2015 at 08:09 AM.
 
Old 03-06-2015, 08:27 AM   #3
sisrnb
LQ Newbie
 
Registered: Dec 2013
Distribution: debian wheezy
Posts: 23

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by NevemTeve View Post
Why did you expect you could?

Anyways, change this:

Code:
old:  PRINTF("ERROR! sem_wait\n");
new:  PRINTF("ERROR! sem_wait errno=d: s\n", errno, strerror (errno));
In my apprehension, using kill() may sometimes affect other threads in the process, but pthread_kill() doesn't.
Maybe I was wrong.
Is that possible with pthread_kill()?

Wow, using strerror() is amazing! Thanks!

Last edited by sisrnb; 03-06-2015 at 08:36 AM.
 
Old 03-06-2015, 10:51 AM   #4
SoftSprocket
Member
 
Registered: Nov 2014
Posts: 399

Rep: Reputation: Disabled
Did you read the man page for pthread_kill? You are sending a signal to the thread that is calling pthread_kill and then exiting. While signal handlers are shared pthread_kill only signals the thread whose id is passed. In other words your program is behaving the way it should.

Here is a signal going both ways -all error checking absent and not ready for prime time:
Code:
#include <pthread.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>

sig_atomic_t ok = 1;

void handle_sig (int i) {
        ok = 0;
}

void* th (void* arg) {
        int i = 0;
        while (ok) {
                sleep (1);
                printf ("d\n", ++i);
                if (arg != NULL) {
                        printf ("sending d\n", SIGUSR1);
                        pthread_kill (*(pthread_t*)arg, SIGUSR1);
                }
        }

        printf ("Exiting\n");
        return arg;
}

int main () {
        signal (SIGUSR1, handle_sig);

        pthread_t tid;
        
        pthread_create (&tid, NULL, th, NULL);

        sleep (5);
        printf ("sending d\n", SIGUSR1);
        pthread_kill (tid, SIGUSR1);
        pthread_join (tid, NULL);

        ok = 1;
        pthread_t pid = getpid ();
        pthread_create (&tid, NULL, th, &pid);
        
        sleep (5);
        pthread_join (tid, NULL);

        printf ("Goodbye\n");


        return 0;
}
It interrupts the thread then sets up another and tries to kill the parent but this causes a sigfault, which I suspect is because you can't signal the parent this way.

Last edited by SoftSprocket; 03-06-2015 at 11:01 AM. Reason: Fix error
 
Old 03-09-2015, 09:30 AM   #5
sisrnb
LQ Newbie
 
Registered: Dec 2013
Distribution: debian wheezy
Posts: 23

Original Poster
Rep: Reputation: Disabled
Smile

Quote:
Originally Posted by SoftSprocket View Post
You are sending a signal to the thread that is calling pthread_kill and then exiting.
I meant to send signal to thread main and I thought I was sending to thread main.
Thanks for your reply! Now I've changed the 4th parameter of pthread_create to '&tid_main' which value is given by running pthread_self() in function main, and it works fine.
My program is changed to:
Code:
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <errno.h>

#define PRINTF(fmt, ...)   printf("%s:%d: " fmt, __FUNCTION__, __LINE__, ## __VA_ARGS__)
#define WAIT_INTERVAL      1000

static sem_t sem;

static void sig_handler_drp(int sig)
{
   if (SIGUSR1 == sig)
   {
      PRINTF("SIGUSR1 received\n");
   }
}
void *thread_drp(void *arg)
{
   usleep(WAIT_INTERVAL);
//   if (kill(getpid(), SIGUSR1))
//   {
//      PRINTF("ERROR! kill\n");
//   }
   if (pthread_kill(*(pthread_t *)arg, SIGUSR1))
   {
      PRINTF("ERROR! pthread_kill\n");
   }
   return NULL;
}
int main(int argc, char ** argv)
{
   struct sigaction sa;
   pthread_t tid;
   pthread_t tid_self = pthread_self();

   memset(&sa, 0, sizeof(struct sigaction));
   sa.sa_handler = sig_handler_drp;
   sigemptyset(&sa.sa_mask);
   sa.sa_flags = 0;
   if (-1 == sigaction(SIGUSR1, &sa, NULL))
   {
      PRINTF("ERROR! sigaction\n");
   }
   if (sem_init(&sem, 0, 0))
   {
      PRINTF("ERROR! sem_init\n");
   }
   if (pthread_create(&tid, NULL, thread_drp, &tid_self))
   {
      PRINTF("ERROR! pthread_create\n");
   }

   if (sem_wait(&sem))
   {
      //PRINTF("ERROR! sem_wait\n");
      PRINTF("ERROR! sem_wait errno=%d: %s\n", errno, strerror (errno));
      if (EINTR == errno)
      {
         PRINTF("ERROR! sem_wait gets EINTR\n");
      }
   }

   if (pthread_join(tid, NULL))
   {
      PRINTF("ERROR! pthread_join\n");
   }
   if (sem_destroy(&sem))
   {
      PRINTF("ERROR! sem_destroy\n");
   }

   return 0;
}
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
LXer: Where Mozilla Ubiquity Failed, Ubuntu HUD will Succeed LXer Syndicated Linux News 0 01-31-2012 05:50 AM
Error: Ns make failed! terbulance129 Linux - Newbie 8 06-11-2011 10:39 AM
LXer: How Google can make Chrome OS succeed LXer Syndicated Linux News 0 03-15-2011 03:11 AM
LXer: Can Digium Succeed Where Red Hat Failed? LXer Syndicated Linux News 0 02-15-2010 08:50 PM
Timers SIGRTMIN is causing Socket Read to error on EINTR wkhoo Programming 1 07-04-2008 11:05 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 04:28 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration