BsiIce 发表于 2015-03-06 19:27

kill能使sem_wait产生EINTR错误,而pthread_kill不能,why?

#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;
}
如上代码,编译后执行输出如下:
sig_handler_drp:19: SIGUSR1 received
main:59: ERROR! sem_wait
main:62: ERROR! sem_wait gets EINTR

如果将kill的代码注释掉,然后pthread_kill的代码打开,则运行后会卡在sem_wait,
为什么pthread_kill不能使使sem_wait产生EINTR错误?

羽剑天涯 发表于 2015-03-10 15:39

你pthread_kill发送给的是thread_drp线程,而sem_wait是在主线程阻塞的,这样主线程不会被打断啊,sem_wait会一直等待的。

BsiIce 发表于 2015-03-11 22:38

本帖最后由 BsiIce 于 2015-03-11 22:42 编辑

回复 2# 羽剑天涯


太感谢了!
原来如此,我发错线程了,我还以为发给线程main了呢,现在我声明个变量tid_self=pthread_self(),然后把pthread_create()的第4个参数改为&tid_self,就OK了。
之前我还以为sig_handler_drp是在线程main中执行的,原来是在thread_drp中执行的。
页: [1]
查看完整版本: kill能使sem_wait产生EINTR错误,而pthread_kill不能,why?