开始全新系统的学习,又是 熟悉的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参数解决。