recv () не прерывается Сигнал в многопоточной среде

Можно просто использовать версию where, которая принимает выражение условия в виде строки, то есть .where("SomeCol > 0.1"). См. https://spark.apache.org/docs/2.4.0/api/java/org/apache/spark/sql/Dataset.html#where-java.lang.String-

17
задан Alex B 27 September 2010 в 23:37
поделиться

4 ответа

Обычно сигналы не прерывают системные вызовы с помощью EINTR. Исторически существовали два возможных поведения доставки сигнала: поведение BSD (системные вызовы автоматически перезапускаются при прерывании сигналом) и поведение Unix System V (системные вызовы возвращают -1 с errno, установленным в EINTR при прерывании сигналом). Linux (ядро) переняла последнее, но разработчики библиотеки GNU C (правильно) сочли поведение BSD гораздо более разумным, и поэтому в современных системах Linux вызов signal (который является функцией библиотеки) приводит к BSD поведение.

POSIX допускает любое поведение, поэтому рекомендуется всегда использовать sigaction, где вы можете установить флаг SA_RESTART или опустить его в зависимости от желаемого поведения. См. Документацию для sigaction здесь:

http://www.opengroup.org/onlinepubs/9699919799/functions/sigaction.html

23
ответ дан 30 November 2019 в 12:06
поделиться

Обработчик сигнала вызывается в том же потоке, который ожидает в recv ()? Вам может понадобиться явно замаскировать SIGINT во всех других потоках с помощью pthread_sigmask ()

4
ответ дан 30 November 2019 в 12:06
поделиться

Вы можете установить тайм-аут в Linux recv: Linux: есть ли чтение или запись из сокета с тайм-аутом?

Когда вы получите сигнал, вызов будет выполнен в классе, выполнив получать.

void* signalThread( void* ptr )
{
    CapturePkts* cap=(CapturePkts*)ptr;
    sigset_t sigSet=cap->getSigSet();
    int sig=-1;
    sigwait(&sigSet,&sig); //signalThread: signal capture thread enabled;
    cout << "signal=" << sig << " caught,ending process" << endl;
    cap->setDone();
    return 0;
}

class CapturePkts
{
     CapturePkts() : _done(false) {}

     sigset_t getSigSet() { return _sigSet; }

     void setDone() {_done=true;}

     bool receive( uint8_t *buffer, int32_t bufSz, int32_t &nbytes)
     {
         bool ret=true;
         while( ! _done ) {
         nbytes = ::recv( _sockid, buffer, bufSz, 0 );
         if(nbytes < 1 ) {
            if (errno == EAGAIN || errno == EWOULDBLOCK) {
               nbytes=0; //wait for next read event
            else
               ret=false;
         }
         return ret;
     }

     private:
     sigset_t _sigSet;
     bool _done;
};
0
ответ дан 30 November 2019 в 12:06
поделиться

В многопоточном приложении нормальные сигналы могут произвольно доставляться в любой поток. Используйте pthread_kill для отправки сигнала в конкретный интересующий поток.

6
ответ дан 30 November 2019 в 12:06
поделиться
Другие вопросы по тегам:

Похожие вопросы: