0

fifo.3 source code:

    #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 source code :

    #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;
}

this is the first time I post code on Stack overflow, so it is in a mess. Above are two C source code. fifo3.c has two thread and thread_write is to write data to named fifo. fifo4.c is to read data from named fifo.

my question:

1) how does the read(pipe_fd, buffer, BUFFER_SIZE) behave when write() is writing data to fifo? If read() can not read data, SHOULD not read() return 0 and then exit, why read() would wait write() to finish write data??? of course, how does write() behave when read() is reading?

2) in fifo3.c , I create two threads, when I create them detached , the program can not run !!! but joinable, they could run correctly !!I do not know why! In theory, they both could function right.

city
  • 2,036
  • 2
  • 32
  • 40

1 Answers1

1

Answer for Question-1:

If read cannot read data it will 'block' till data arrives, this is called blocking mode read. Incase of a blocking mode read, the read call blocks till a data arrives. If you wish to change it to non-blocking mode, you can use fcntl functionality, if the same is supported.

For other queries, it is best that you read about it through man pages as a concise answer will be difficult.

Answer for Question-2:

When you create a thread detached, it means the created threads are not bound to the parent thread which creates it. So, the parent thread will just exit, if it completes it's work. If the parent happens to be the main thread, then when it exits the process also will exit, which will cause program not to run.

Jay
  • 24,173
  • 25
  • 93
  • 141
  • to Question 1, if read() will block to wait the data arrives, when would it exit and how would it know the data it is waiting for will arrive or not arrive forever and then decide to continue waiting or exiting? to Question 2, if in the program there are three processes, and each creates several threads which are hoped to run infinitely, should I create them with joinable attribute? – city Mar 10 '12 at 11:14
  • 1
    `fcntl`, not `ioctl`, is able to change to nonblocking mode. – R.. GitHub STOP HELPING ICE Mar 10 '12 at 12:34
  • @City, You could try select (http://linux.die.net/man/2/select) and non-blocking file descriptor for Question-1. Blocking read will exit if either some data arrives or the peer closes the connection from other side. For Question-2 http://stackoverflow.com/questions/4666628/does-child-threads-exit-when-the-parent-thread-terminates should answer your query – Jay Mar 12 '12 at 05:03