【问题标题】:Futex Error in C application that is using mutex and epoll使用互斥锁和 epoll 的 C 应用程序中的 Futex 错误
【发布时间】:2019-07-31 03:31:26
【问题描述】:

我正在运行 epoll 来处理网络连接。我认为一切都运行良好。

现在我正在尝试从子进程连接到 Postgresql 数据库。我有 4 个子进程。

有时当我尝试连接到服务器时。它挂起。

有时我会收到此错误 fserver: tpp.c:84: __pthread_tpp_change_priority: 断言`new_prio

如果有人能够对我的代码提出建议,我们将不胜感激。谢谢

如果我删除 Postgresql 连接代码,问题就会消失。

/******CHILD PROCESS **************/
void childProcess()
{
  const char conninfo[] = "postgresql://postgres@localhost?port=5432&dbname=ram&password=xxx";
  PGconn *conn = PQconnectdb(conninfo);
  const ConnStatusType connStatusType = PQstatus(conn);
  if (connStatusType == CONNECTION_BAD) {
    printf("pg connection not OK");
    if (conn) {
      PQfinish(conn);
    }
    exit(1);
  } else {
    printf("pg connection OK");
  }

 int efd = epoll_create1(0);
 if(efd == -1)
 {
   perror("Epoll Creation Failed\n");
 } 

 nonblocksocket(&p2c_var);
 struct epoll_event event0;
 event0.data.fd = p2c_var;
 event0.events = EPOLLIN | EPOLLET;

 if(epoll_ctl(efd,EPOLL_CTL_ADD,p2c_var,&event0) == -1)
 {
  perror("First Failed to add file descriptor to epoll watch list\n");
 } 

 nonblocksocket(&c2p_var);
 struct epoll_event event1;
 event1.data.fd = c2p_var;
 event1.events = EPOLLOUT | EPOLLET;

 if(epoll_ctl(efd,EPOLL_CTL_ADD,c2p_var,&event1) == -1)
 {
  perror("Second Failed to add file descriptor to epoll watch list\n");
 } 


 struct epoll_event *ttlevents;
 ttlevents = calloc(MAXEVENTS, sizeof(event0));

 int head = 0,tail = 0;
 pthread_mutex_t buflock;
 pthread_mutex_t fdlock;
 int bufhead=0,buftail=0;
 struct fifoarr *fifoptr = (struct fifoarr *) calloc(QSIZE,sizeof(struct fifoarr));
 int co = 0;
 char st[1050];
 memset(st,0,sizeof(st));
 st[0] = 1; 

while(1)
{
int eventcount = epoll_wait(efd,ttlevents,MAXEVENTS,-1);
for(int i =0;i<eventcount;i++)
{
if ((ttlevents[i].events & EPOLLERR) || (ttlevents[i].events & EPOLLHUP))
{
/* An error has occured on this fd, or the socket is not ready for reading (why were we notified then?) */
  fprintf (stderr, "epoll error\n");
  close (ttlevents[i].data.fd);
  continue;
}

if(ttlevents[i].events & EPOLLOUT)
{
 if(ttlevents[i].data.fd == c2p_var) 
 {
   pthread_mutex_lock(&buflock);
   int bufval = popfd(&bufhead,&buftail);
   if(bufval != -1)
   {
     write(c2p_var,fifoptr[bufval].buffer,sizeof(fifoptr[bufval].buffer));
   }
   pthread_mutex_unlock(&buflock);
  }
 }

 if(ttlevents[i].events & EPOLLIN)
 {
   if(ttlevents[i].data.fd == p2c_var) 
   {
     char buffer[1050];

    while(1)
    {
     memset(buffer,0,sizeof(buffer));
     int c = read(ttlevents[i].data.fd,buffer,sizeof(buffer));
     if(c == -1)
     {
      if(errno == EAGAIN)
      {
    printf("Completed Reading From Parent Process\n");
        break;
      }         
     }
     if(c == 0)
     {
    printf("Parent terminated Connection.\n");
        break;  
     }

     if(buffer[0] != 1) 
     {
       pthread_mutex_lock(&buflock);
       int bufval = pushfd(&bufhead);
       if(bufval != -1)
        {        memset(fifoptr[bufval].buffer,0,sizeof(fifoptr[bufval].buffer));    memcpy(fifoptr[bufval].buffer,buffer,sizeof(buffer));
       // processRequest(fifoptr[bufval].buffer,conn);
       write(c2p_var,&st,sizeof(st));
        }   
        pthread_mutex_unlock(&buflock);
      }//buffer[0]
 }//While
}
}//if epollin
} //for
}//while(1)

PQfinish(conn);
}

程序往往会挂起。

【问题讨论】:

  • 你检查过你没有用尽 PostgreSQL 上的max_connections 吗?
  • 我认为我还没有耗尽 max_connection,因为当我尝试 telnet 到服务器时也会出现问题。它有时也会发生在一个连接上。当我尝试 strace 时,我看到子进程正在等待 futex -> futex(0x7ffc0db430b0, FUTEX_WAIT, 2, NULL
  • 这对我来说看起来太低级了。

标签: linux postgresql epoll


【解决方案1】:

现在它正在工作。

似乎是互斥锁是问题的原因。

感谢所有查看我的代码的人。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-09-10
    • 2011-01-15
    • 2011-08-10
    • 1970-01-01
    • 1970-01-01
    • 2015-10-06
    • 2014-05-30
    • 1970-01-01
    相关资源
    最近更新 更多