2017-03-28 49 views
0

我有一个使用pthread,特别是pthread_cond_wait的c代码。我的问题是,如果我使用subprocess.Popen从我的python代码调用此c可执行文件,它不能正常工作,它看起来像缓冲数据而不是实时打印。以下是我的c代码:在子进程中处理pthread_cond_wait.Popen

#include <unistd.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <ctype.h> 
#include <string.h> 
#include <pthread.h> 
#include "linux_nfc_api.h" 

pthread_cond_t condition = PTHREAD_COND_INITIALIZER; 
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 

nfcTagCallback_t g_TagCB; 
nfc_tag_info_t g_tagInfos; 

void onTagArrival(nfc_tag_info_t *pTagInfo){ 
    printf("Tag detected\n"); 
    int i = 0; 
    for(i = 0x00; i < (*pTagInfo).uid_length; i++){ 
     printf("%02X ", (unsigned char) (*pTagInfo).uid[i]); 
    } 
    g_tagInfos = *pTagInfo; 
    pthread_cond_signal(&condition); 
} 

void onTagDeparture(void){ 
    printf("Tag removed\n"); 
} 

int main(int argc, char ** argv) { 
    g_TagCB.onTagArrival = onTagArrival; 
    g_TagCB.onTagDeparture = onTagDeparture; 
    nfcManager_doInitialize(); 
    nfcManager_registerTagCallback(&g_TagCB); 
    nfcManager_enableDiscovery(DEFAULT_NFA_TECH_MASK, 0x01, 0, 0); 

    unsigned char page = 0x00; 
    int i; 
    int res = 0x00; 
    unsigned char cmd_send[3] = {0x02, 0x20, 0x00}; 
    unsigned char cmd_response[255]; 
    printf("Waiting for tag...\n"); 
    do{ 
     pthread_cond_wait(&condition, &mutex); //problem 

     memset(cmd_response, 0x00, 255); 

     printf("SEND APDU: "); 
     for(i=0; i < sizeof(cmd_send); i++){ 
      printf("%02X ",cmd_send[i]); 
     } 

     res = nfcTag_transceive(g_tagInfos.handle, cmd_send, 3, cmd_response, 255, 500); 
     printf("RECV APDU (%d): ",res); 
     for(i=0; i<res; i++){ 
      printf("%02X ",cmd_response[i]); 
     } 
    }while(1); 
    nfcManager_doDeinitialize(); 
} 

我发现问题是由于pthread_cond_wait。我的Python继续缓冲,并且它在python程序关闭之后打印所有数据而不是实时。以下是我的Python代码:

import sys 
from subprocess import Popen, PIPE, call 

proc = Popen(['App'], stdout=PIPE) 
for line in iter(proc.stdout.readline, ''): 
    print line 

因此,有没有什么办法来处理这种情况考虑到一个事实我无法改变我的C代码?

+0

是由于条件变量或管道是块缓冲的事实,只会在输出大量数据后才将数据从子进程发回您的readline? – tdelaney

+0

是的管道是块缓冲。 – prattom

+0

如果你在一个类似linux的系统上,'pty'模块或甚至'pexpect'都可能适用于你。 – tdelaney

回答

0

尝试:

import sys 
from subprocess import Popen, PIPE, call 

proc = Popen(['App'], stdout=PIPE, stderr=PIPE) 
output, errors = proc.communicate() 
print output.decode() 

为什么:

见python文档:

警告 - 使用通信(),而不是.stdin.write,.stdout.read或 .stderr.read以避免由于任何其他操作系统管道缓冲区填充和阻塞子进程而导致的死锁。