city
city

Reputation: 2154

how the system call read and write behave and why the threads cannot work?

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.

Upvotes: 0

Views: 370

Answers (1)

Jay
Jay

Reputation: 24905

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.

Upvotes: 1

Related Questions