我在Android 5.x上使用Python。 由于Android将stderr和stdout重定向到/ dev / null,因此我有一个C例程将其复制并允许我读取它,并且在Python中我编写了一个脚本来强制每次写入均引起刷新,否则我不会得到消息及时处理。

所以我的问题是,如果我关闭我在stderr或stdout所在的线程,然后Python尝试写到我已停止读取的任何内容,Python会引发异常并抱怨管道损坏。

我想我对管道和dup2不够了解。 我以为问题是线程死时stdout不再有写入位置。 但是我认为管道和dup2只是给我一种访问它的方式,而不是控制。 任何输入将不胜感激。

这是我用来读取标准输出的C代码

void startStdOutLogging()
{
    LOGE("Starting up STDOUT");

    // This will make our stderr buffer wake on newline _IOLBF instead of Nonbuffered _IONBF
    setvbuf(stdout, 0, _IOLBF, 0);

    /* create the pipe and redirect stdout */
    pipe(mOutFile);
    dup2(mOutFile[1], STDOUT_FILENO);

    /* spawn the logging thread */
    if(pthread_create(&mOutThread, nullptr, out_thread_func, nullptr) == -1)
    {
        LOGE("Failed to create Standard Out Thread");
        return;
    }
    return;
}

static void *out_thread_func(void*)
{
    ssize_t lReadSize;
    char lReadBuffer[2048];

    // This is what we have left to send
    std::string lUnProcessedBuffer("");

    lReadBuffer[0] = '\0';

    // Flag to tell the rest of the app we are alive
    mSTDOUTIsRunning = true;

    std::size_t lPos(0);                // the position of our \n
    std::string lWriteBuffer("");       // What we plan to store the stuff to write out in
    std::string lLastWriteBuffer("");   // What was the last message we wrote

    // Set this read non-blocking
    fcntl(mOutFile[0], F_SETFL, fcntl(mOutFile[0], F_GETFL) | O_NONBLOCK);

    // Stay running until someone sets this flag to tell us to die
    while(mKeepStdOutRunning == true)
    {
        lReadSize = read(mOutFile[0], lReadBuffer, sizeof lReadBuffer - 1);

        if ( lReadSize <= 0 )
        {
            // we read nothing on the socket, if there is still unwritten text, do it now
            if ( !lUnProcessedBuffer.empty() )
            {
                __android_log_write(ANDROID_LOG_DEBUG, "stdout", lUnProcessedBuffer.c_str());
                lUnProcessedBuffer.clear();
            }

            // We found nothing, wait
            usleep(250000); // 250ms
            continue;
        }

        // Find the position of the \n in our string
        lUnProcessedBuffer.append(lReadBuffer);

        // now we have a buffer, might be more then 1 line, keep writing until we have
        // written each line
        while ( (lPos = lUnProcessedBuffer.find_first_of("\n")) != std::string::npos )
        {
            // We know where it is.
            lWriteBuffer = lUnProcessedBuffer.substr(0, ++lPos);
            lUnProcessedBuffer = lUnProcessedBuffer.substr(lPos);

            if ( lWriteBuffer.compare(lLastWriteBuffer) == 0 )
            {
                LOGD("We have a duplicate message.  Ignoring");
                continue;
            }

            lLastWriteBuffer = lWriteBuffer;

            // Log it, and write it to MD if we need to
            __android_log_write(ANDROID_LOG_DEBUG, "stdout", lWriteBuffer.c_str());
         }
    }

    // Close the files, we are about to terminate.  This is big, else you get broken pipe
    close(mOutFile[0]);
    close(mOutFile[1]);

    LOGE("Standard Out logging thread is shutting down");

    // Let the app know we are done
    mSTDOUTIsRunning = false;

    return 0;
}

这是Python代码

    # Set it to our Unbuffered custom
    sys.stdout = Unbuffered(sys.stdout)
    sys.stderr = Unbuffered(sys.stderr)

class Unbuffered(object):
   def __init__(self, stream):
       self.stream = stream
   def write(self, data):
       self.stream.write(data)
       self.stream.flush()
   def __getattr__(self, attr):
       return getattr(self.stream, attr)

  ask by GR Envoy translate from so

本文未有回复,本站智能推荐:

1回复

管道在android ndk中使用C代码打开文件时返回null

我正在尝试向我的Android应用程序编写一些本地代码,该应用程序使用2个文件管道在Java代码和本地代码之间进行通信。 最终目的是使本机代码通过网络与Java代码进行通信,而只是侦听管道的两端是否有传入和传出数据。 这是我从Java应用程序调用的代码: 由此我得到输出: 这
1回复

F_SETPIPE_SZ与Android NDK解除绑定

我正在使用NDK为Android构建jni库,我需要更改管道缓冲区的大小,但是fcntl(pipe_fd[0], F_SETPIPE_SZ, 1048576); 编译失败,出现错误消息“ F_SETPIPE_SZ undelcard”,我已经在C ++源文件的开头添加了#define _GNU
2回复

Android中的管道问题

我有一部分代码是写成从Android本机代码写入管道的。 但是,该程序似乎并未阻塞写入操作。 根据我的理解,程序应该在写入之前阻塞,直到有一个最终从管道读取的进程。 请让我知道下面的代码有什么问题,以及为什么不阻塞而退出。
1回复

如何在C(Android NDK)中杀死子线程?

在你告诉我我不应该杀死线程然后发送信号/设置一个标志让他们作出反应之前,让我解释一下这个场景: 我正在使用OpenSL API在Android NDK中开发音频播放器(播放本地mp3文件),但Android实现有一个错误,如果我对文件重复执行搜索操作,该线程可悲地挂起一种内部死锁当我尝试释
1回复

ndk中的LocalBroadcastManager

是否可以在Java接口中使用LocalBroadcastManager发送或接收数据? 在ndk中发送或接收( c或c ++ )? 我知道如何在Java中实现LocalBroadcastManager ,但我想知道是否有可能在c语言中使用它来交换数据,我在哪里可以了解到此功能。 因
1回复

当我尝试将字符串复制时,Android NDK strcpy崩溃

这就是我想要做的: 哪里: 我是从SDK中获得的,所以不确定它是什么。 如果我登录: LOGI("VIDYO_CLIENT_OUT_EVENT_VIDEO_FRAME_RECEIVED AskViewType callerURI 1 REAL: %s" ,reqPartic
2回复

Android NDK可以在Android共享库中包含一个Windows dll吗?

甚至可以在ndk-build命令中链接/包含一个dll文件,并生成一个可以从android java代码访问dll函数的共享库。 我一直在尝试这样做,我尝试使用SWIG创建一个java包装器代码到dll而我没有成功,然后我开始认为它甚至可能! 谢谢。
1回复

NDK:尝试建立另一个.so时使用用户创建的.so

我正在尝试将使用NDK生成的某些.so链接到新的.so,因为旧的.so包含了要在新.so中使用的函数的定义,所以我尝试创建该.so。 我已经尝试过这个Android.mk: 我也尝试过在stackoverflow NDK中找到的这种方法-如何在另一个项目中使用生成的.so库,但由于
1回复

构建ndk库时出错

我正在尝试从jni文件夹中的netguard本机库创建一个.so文件,但是在执行“ ndk-build”后出现此错误“ collect2 ld返回了1个退出状态”。 请我希望有人帮助创建一个.so文件。 项目路径: https : //github.com/M66B/NetGuard
3回复

将数据从正在运行的C代码链接到正在运行的Python代码[关闭]

我正在C代码中接收数据,当前我唯一能做的就是在屏幕上打印数据。 我想知道是否有可能将数据发送到正在运行的Python代码,以便能够进一步处理数据,而不仅仅是在屏幕上打印数据? 数据为数组形式。 将在屏幕上打印数据的设备将运行Python代码。 我这样做是为了避免将数据保存在文件中,然