linux学习——前期一些问题验证(文件描述符、线程)

 

        开始全新系统的学习,又是 熟悉的hello world模式入门。公司项目逼得紧迫,都找不出时间开始系统的学习,以前看过linux方面的书籍早就忘的一干二净了,这几天看了实际代码,今天验证一些想法。首先编写一个简单的程序如下:

#include <stdio.h>  
#include <stdlib.h>
#include <fcntl.h>    // About file operation
#include <pthread.h>  // About thread operation

#define MAX(x,y) (((x)>(y)) ? (x) : (y))
static pthread_t    fd_test_thread_id;
static fd,fd1;

void *fd_test(void *data)

{
    fd_set fd_fds;
    int fd_nfds = 0;
    int rc;
    static int test_num = 0;

    pid_t pid;
    pid = getpid();
    printf("%s [E] \n",__func__);
    fd1 = open("./test.txt", O_CREAT|O_RDONLY);    // 已只读模式打开当前目录下的test.txt文件。O_CREAT文件若不存在就新建。

    if(fd1 < 0)
    {
        printf("Open test error! pid=%d \n", pid);
    }
    else
    {
        printf("test fd1:%d ! pid=%d \n", fd1, pid);   // 这里验证文件描述符为4。
    }

    do{
    test_num++;
    struct timeval fd_timeout;
    fd_timeout.tv_usec = 0;
    fd_timeout.tv_sec = 5;
    FD_ZERO(&fd_fds);
    FD_SET(fd, &fd_fds);
    FD_SET(fd1, &fd_fds);
    fd_nfds = MAX(fd, fd1);

    printf("here fd=%d, fd1=%d, fd_nfds=%d!\n", fd, fd1, fd_nfds);  
    rc = select(fd_nfds+1, &fd_fds, NULL, NULL, &fd_timeout);
    if(rc == 0)
    {
        printf("fd thread select timeout! \n");
        continue;
    }
    else if(rc < 0)
    {
        printf("Select error! \n");
        continue;
    }
    else if(rc)
    {
 printf("Something select! \n");
        if(FD_ISSET(fd, &fd_fds))
        {  // There have noting happend in fd, why function is running here?
             printf("Select fd occour! \n");
        }

        if(FD_ISSET(fd1, &fd_fds))
        {  // There have noting happend in fd1, why function is running here?
             printf("Select fd1 occour! \n");
        }
    }
    }while(test_num<3);

    printf("%s [X] \n", __func__);
}

int main(void)
{
    int err;
    int ret_val;
    pid_t pid;

    pid = getpid();
    fd = open("./tmp.txt", O_CREAT|O_RDONLY);    // 已只读模式打开当前目录下的tmp.txt文件。O_CREAT文件若不存在就新建。
    if(fd < 0)
    {
        printf("Open error! pid=%d \n", pid);
    }
    else
    {
        printf("fd:%d ! pid=%d \n", fd, pid);   // 这里验证文件描述符为3。
    }

    err = pthread_create(&fd_test_thread_id, NULL, fd_test, NULL);   // Creat a new thread, but not running.
    if(err != 0)
    {
        printf("Can't create thread! \n");
    }

    printf("thread join! \n");
    if(pthread_join(fd_test_thread_id, (void**)&ret_val)){  // Joint this thread and running it.
        printf("Join test thread failed! \n");
    }
    printf("thread join return:%d \n", ret_val);

    printf("Main exit! \n");

    return 0;
}

        在上面这个例程里面,主要验证前段时间零散查看一些代码资料的疑惑:

1.验证了一下文件描述符的一些概念,创建一个新的进程时0、1和2三个文件描述符将默认给标准IO及ERROR,新打开的文件将从3开始。

2.创建了一个新的线程,通过LOG发现pthread_create创建了此线程,但并未运行它?下面再调用pthread_join函数加入此线程,查阅一些资料得出此函数用来加入某个线程,并开始执行,这个函数常用来阻塞某个进程或线程,等待待加入线程(这里是fd_test_thread_id)的结束。

3.在新建的线程里面验证了一下select机制,不过令人疑惑的是fd,fd1两个文件没有获得操作,但是LOG显示一直在执行。不知原因,还需要后续进一步学习。

4.创建子线程时复制了父进程的文件描述符表,但是在子线程中如何来使用?比如上例中复制了fd这个描述符,但是该如何使用?后面只能通过静态变量方法调用,需要后续进一步学习了解。

 

PS:

1.使用thread函数时编译出现如下错误:

undefined reference to 'pthread_create'
undefined reference to 'pthread_join'
百度了解到pthread 库不是 Linux 系统默认的库,连接时需要使用静态库 libpthread.a,在编译时加 -lpthread参数解决。

你可能感兴趣的:(linux学习——前期一些问题验证(文件描述符、线程))