2010-05-19 3 views
0

다른 POSIX 스레드에 대해 printf (3)와 같은 표준 출력에 대해 다른 리다이렉션을 수행 할 가능성이 있습니까? 표준 입력은 어떻게됩니까?POSIX 스레드마다 다른 표준 스트림

표준 입출력을 기반으로하는 많은 코드가 있으며이 코드를 프로세스가 아닌 다른 POSIX 스레드로 분리 할 수 ​​있습니다. 리눅스 운영 체제, C 표준 라이브러리. printf()를 fprintf()와이 스타일로 바꾸는 코드를 리펙토링 할 수 있음을 알고 있습니다. 그러나이 경우 이전 코드에없는 일종의 컨텍스트를 제공해야합니다.

아무도 더 좋은 아이디어가 없다 (아래 코드를보십시오)?

#include <pthread.h> 
#include <stdio.h> 

void* different_thread(void*) 
{ 
    // Something to redirect standard output which doesn't affect main thread. 
    // ... 

    // printf() shall go to different stream. 
    printf("subthread test\n"); 

    return NULL; 
} 

int main() 
{ 
    pthread_t id; 
    pthread_create(&id, NULL, different_thread, NULL); 

    // In main thread things should be printed normally... 
    printf("main thread test\n"); 

    pthread_join(id, NULL); 
    return 0; 
} 

답변

4

clone을 사용하여 스레드를 만들면 원하는대로 할 수 있지만 POSIX.1에서는 스레드가 열린 파일 디스크립터를 공유해야한다고 말합니다.

시도 할 수있는 몇 가지 트릭이 있지만 실제로는 호출을 FILE * 인수 인수 기능으로 변환해야합니다.

+0

기술적으로 정말 좋은 점은 기술적으로 원래의 과제를 해결할 수 있었지만 상황을 더 깊이 분석 한 후에 미래에 코드를 재사용 할 계획 이었으므로 코드 재 작업을 선호했고 fork()와 비슷한 것을 소개하지 않기를 바란다.). –

0

당신은 내가/같은 O 기능 "의 printf()가"그럼 내가이 작업을 수행 할 수있는 생각할 수있는 유일한 방법은 내가/O 라이브러리는 스레드 별 지원하는 표준을위한 표준을 사용하여 주장하는 경우 스레드 로컬 데이터 구조를 사용하는 I/O ("errno"는 스레드 로컬 오류 번호를 반환하는 함수를 호출하는 매크로와 비슷 함). 나는 이것을 수행하는 표준 I/O의 구현을 모른다.

+0

예, 스레드 로컬 표준 I/O 리디렉션을 수행하는 방법이 필요했습니다. 원본 코드는 VxWorks에서 이식되었으며이 운영 체제에는 이와 같은 기본 인터페이스가 있습니다 (원래 작성자가 사용했습니다). 이제는 I/O 컨텍스트를 지원하기 위해 모든 코드를 요청하거나 확장하는 방법을 찾아야합니다. 나는 운이 좋은 편이어서 비교적 쉬운 길을 찾았습니다. –

1

On * nix 시스템에서는 파일 설명자에 걸친 stdio 계층과 파일 설명자가 프로세스에 대해 전역입니다. 따라서 변경하지 않고 원하는 것을 할 수있는 방법이 없습니다 뭔가. 가장 좋은 방법은 fprintf()를 사용하여 코드를 다시 작성하는 것입니다. 여기에는 arglist에 인수를 추가하는 작업이 포함되기 때문에 실제 코드를 수정하지 않고도 전 처리기를 사용하여 목표를 달성 할 수 있는지 확신 할 수 없습니다.

새로운 프로세스를 만들 수없는 이유를 분명히 알 수 있습니까? 문제는 그 각도에서 풀 수 있습니다. 사용하려는 다른 모든 표준 입출력 기능

#undef printf 
#define printf(fmt, ...) fprintf(my_threadlocal_stdout, fmt, __VA_ARGS__) 

마찬가지로 :

1

당신이 스레드 로컬 저장소가있는 경우, 당신은 뭔가를 할 수 있습니다. 물론 동일한 이름을 다시 정의하지 않는 것이 좋지만 대체 방법으로 원본 파일을 검색하고 대체하여 대체 이름을 사용하는 것이 좋습니다.

BTW 컴파일러에 대한 스레드 로컬 저장소 확장이 없어도 사용할 호출 스레드에 대해 FILE *을 반환하는 함수 호출을 사용할 수 있습니다.

+0

실제로 스레드 로컬 저장소가 원래의 경우에 마침내 사용되었지만 예측할 수없는 결과가 발생할 수 있으므로 전역 printf 오버로드에 반대합니다. 스레드 로컬 스토리지를 기반으로 최소한 재 작업 된 인터페이스와 내부적으로 숨겨진 컨텍스트에서 머물렀다. 이것은 모두 호환되는 인터페이스와 좋은 작업 솔루션을 제공했습니다.제한은 클라이언트 스레드 당 하나의 컨텍스트로서 허용됩니다. –