2017-03-28 47 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以避免由於任何其他操作系統管道緩衝區填充和阻塞子進程而導致的死鎖。