2012-03-10 64 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; 
} 

这是我第一次张贴在堆栈溢出代码,因此它是一个烂摊子。 以上是两个C源代码。 fifo3.c有两个线程,thread_write是将数据写入到命名的fifo。 012ofifo4.c是从命名的fifo读取数据。

我的问题:

1)如何读(pipe_fd,缓冲,BUFFER_SIZE)时,write()方法将数据写入FIFO的行为?如果read()不能读取数据,不应该读取()返回0,然后退出,为什么read()会等待write()来完成写入数据?当然,read()读取时write()如何表现?

2)在fifo3.c中,我创建了两个线程,当我创建它们分离时,程序无法运行! 但可以连接,它们可以正确运行!!我不知道为什么!理论上,它们都可以正常运作。

的问题-1

回答

1

答:

如果读取无法读取数据,它也会“块”,直到数据到达,这就是所谓的阻塞模式读取。考虑到阻塞模式读取,读取呼叫阻塞直到数据到达。如果您希望将其更改为非阻塞模式,则可以使用fcntl功能(如果支持相同的功能)。

对于其他查询,最好通过手册页阅读它,因为简明的回答将很困难。

回答问题2:

当您创建分离的线程,这意味着创建的线程没有绑定到创建它的父线程。所以,如果父线程完成了它的工作,它就会退出。如果父母碰巧是主线程,那么退出时该进程也会退出,这将导致程序不能运行。

+0

对于问题1,如果read()将阻止等待数据到达,它何时会退出,它将如何知道它正在等待的数据将会到达还是不会永远到达,然后决定继续等待还是退出?到问题2,如果在程序中有三个进程,并且每个都创建了几个希望无限运行的线程,我应该使用可连接属性创建它们吗? – city 2012-03-10 11:14:58

+1

'fcntl',而不是'ioctl',能够转换到非阻塞模式。 – 2012-03-10 12:34:28

+0

@R,谢谢。已编辑和更新。 :) – Jay 2012-03-12 04:28:01

相关问题