2012-03-10 10 views
0

fifo.3ソースコード:システムコールの読み取りと書き込みの動作とスレッドが機能しない理由

#include <unistd.h> 
    #include <stdlib.h> 
    #include <stdio.h> 
    #include <string.h> 
    #include <fcntl.h> 
    #include <limits.h> 
    #include <sys/types.h> 
    #include <sys/stat.h> 
    #include <pthread.h> 
    #include <time.h> 

    #define FIFO_NAME "/tmp/my_fifo" 
    #define BUFFER_SIZE PIPE_BUF //4096 
    #define TEN_MEG (1024 * 1024 * 1) 


void* thread_tick(void* arg) 
{ 
    int count =0; 
    while(count < 4){ 
    printf("hello, world!\n"); 
    sleep(1); 
    count++; 
    } 
} 

void* thread_write(void* arg) 
{ 
    int pipe_fd; 
    int res; 
    int bytes_sent = 0; 
    char buffer[BUFFER_SIZE ]; 
    int count=0;  

    if (access(FIFO_NAME, F_OK) == -1) { 
     res = mkfifo(FIFO_NAME, 0777); 
     if (res != 0) { 
      fprintf(stderr, "Could not create fifo %s\n", FIFO_NAME); 
      exit(EXIT_FAILURE); 
     } 
    } 
    while(count < 10){ 
    printf("write: Process %d opening FIFO O_WRONLY\n", getpid()); 
    pipe_fd = open(FIFO_NAME, O_WRONLY); 
    printf("write: Process %d result %d \n", getpid(), pipe_fd); 

    if (pipe_fd != -1) { 
     while(bytes_sent < TEN_MEG) { 
      res = write(pipe_fd, buffer, BUFFER_SIZE); 
      if (res == -1) { 
       fprintf(stderr, "Write error on pipe\n"); 
       exit(EXIT_FAILURE); 
      } 
      bytes_sent += res; 
     } 
     (void)close(pipe_fd); 
    } 
    else { 
     exit(EXIT_FAILURE); 
    } 

    printf("write: Process %d finished , count =%d\n", getpid(),count); 
    count++; 
    } 
} 


void CreateThread(void* (*start_routine)(void*), void* arg,int stacksize, int priority) 
{ 
    pthread_t app_thread; 
    pthread_attr_t thread_attr; 
    int res; 

    int max_priority; 
     int min_priority; 
     struct sched_param scheduling_value; 

    res = pthread_attr_init(&thread_attr); 
    if (res != 0) { 
     perror("Attribute creation failed\n"); 
     exit(EXIT_FAILURE); 
    } 
     res = pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED); 
    if (res != 0) { 
     perror("Setting detached attribute failed"); 
     exit(EXIT_FAILURE); 
    } 
    res = pthread_attr_setstacksize(&thread_attr, stacksize); 
    if (res != 0) { 
     perror("Set stack size failed\n"); 
     exit(EXIT_FAILURE); 
    } 

    res = pthread_attr_setschedpolicy(&thread_attr, SCHED_RR); 
    if (res != 0) { 
     perror("Setting schedpolicy failed"); 
     exit(EXIT_FAILURE); 
    } 

    max_priority = sched_get_priority_max(SCHED_RR); 
    min_priority = sched_get_priority_min(SCHED_RR); 
    scheduling_value.sched_priority = priority; 
    res = pthread_attr_setschedparam(&thread_attr, &scheduling_value); 
    if (res != 0) { 
     perror("Setting schedpolicy failed"); 
     exit(EXIT_FAILURE); 
    } 

    res = pthread_create(&app_thread, &thread_attr, (*start_routine), arg); 
    if(res != 0){ 
     perror("Thread creation failed\n"); 
     exit(EXIT_FAILURE); 
     } 
    pthread_attr_destroy(&thread_attr); 

    //res = pthread_join(app_thread ,0); 
    //return app_thread; 
} 

int main() 
{ 
    CreateThread(thread_write, 0, 50000, 99); 
    CreateThread(thread_tick, 0, 50000, 98); 
    // pthread_join(w,0); 
    // pthread_join(t ,0); 
    return 0; 
} 

fifo.4ソースコード:

#include <unistd.h> 
    #include <stdlib.h> 
    #include <stdio.h> 
    #include <string.h> 
    #include <fcntl.h> 
    #include <limits.h> 
    #include <sys/types.h> 
    #include <sys/stat.h> 

    #define FIFO_NAME "/tmp/my_fifo" 
    #define BUFFER_SIZE PIPE_BUF //4096 

int main() 
{ 
    int pipe_fd; 
    int res; 
    char buffer[BUFFER_SIZE ]; 
    int bytes_read = 0; 
    int count = 0; 

    memset(buffer, '\0', sizeof(buffer)); 

    while(count < 10){ 
    printf("read: Process %d opening FIFO O_RDONLY\n", getpid()); 
    pipe_fd = open(FIFO_NAME, O_RDONLY); 
    printf("read: Process %d result %d\n", getpid(), pipe_fd); 

    if (pipe_fd != -1) { 
     do { 
      res = read(pipe_fd, buffer, BUFFER_SIZE); 
      bytes_read += res; 
     } while (res > 0); 
     (void)close(pipe_fd); 
    } 
    else { 
     exit(EXIT_FAILURE); 
    } 

    printf("read: Process %d finished, %d bytes read , count =%d\n", getpid(), bytes_read,count); 
    count++; 
    } 
    return 0; 
} 

これは私は、スタックオーバーフローにコードを投稿する最初の時間であるので、混乱しています。 上記は2つのCソースコードです。 fifo3.cには2つのスレッドがあり、thread_writeはfifoという名前のデータを書き込みます。 fifo4.cはfifoという名前のデータを読み込みます。

私の質問:

1)FIFOにデータを書き込んでいるとき、書き込み()どのように読み取り(pipe_fd、バッファ、BUFFER_SIZE)が振る舞うのでしょうか? read()がデータを読み取ることができない場合、read()は0を返してから終了しなければならない(SHOULD NOT)、なぜwrite()がデータの書き込みを終了するのを待つのか?もちろん、read()が読んでいるときにwrite()はどのように動作しますか?

2)fifo3.cでは2つのスレッドを作成しますが、それらを切り離して作成すると、プログラムは実行できません。 でも参加できますが、正常に動作することがあります。理由はわかりません! 理論的には、両方とも正しく機能する可能性があります。質問-1用

答えて

1

回答:読み出したデータを読み取ることができない場合は

それは「ブロック」意志のデータが到着するまで、これがモードの読み込みをブロックと呼ばれています。ブロッキングモードが発生すると、データが到着するまでブロックがブロックされます。ノンブロッキングモードに変更したい場合は、fcntl機能がサポートされていればそれを使うことができます。

他のクエリについては、簡潔な答えが難しいため、マニュアルページから読むことをお勧めします。質問-2用

回答:あなたは切り離されたスレッドを作成するとき

、それが作成されたスレッドが、それを作成し、親スレッドにバインドされていないことを意味します。親スレッドは、作業が完了すると終了します。親スレッドが主スレッドである場合、プロセスを終了すると終了し、プログラムが実行されなくなります。

+0

質問1、read()がデータの到着を待つのをブロックすると、いつ終了するのか、そしてそれが待っているデータが到着するかどうか、そして永遠に到着していないことをどのように知っていますか?質問2には、プログラム内に3つのプロセスがあり、それぞれが無限に動作することが期待されるいくつかのスレッドを作成する場合、結合可能な属性でそれらを作成する必要がありますか? – city

+1

'ioctl'ではなく' fcntl'が非ブロックモードに変更できます。 –

+0

@R、ありがとう。編集して更新しました。 :) – Jay

関連する問題