linux poll操作read write操作使用
/*poll 阻塞的使用:poll就是对描述符进行监听,和select类似,但是poll没有最大描述符的限制,并且poll的描述符使用之后不会被清空,而select每次使用之后都要重新设置.不过他俩作用是一样的,进行阻塞操作.通过调用poll之后,内核可以告诉我们是否可以读写操作.pollfd结构体定义如下:struct pollfd {
·
/*
poll 阻塞的使用:
通过调用poll之后,内核可以告诉我们是否可以读写操作.
pollfd结构体定义如下:
struct pollfd {
int fd; // 文件描述符
short events; // 等待的事件
short revents; // 实际发生了的事件
} ;
/*
每一个pollfd结构体指定了一个被监视的文件描述符,可以传递多个结构体,指示poll()监视多个文件描述符。每个结构体的events域是监视该文件描述符的事件掩码,由用户来设置这个域。revents域是文件描述符的操作结果事件掩码,内核在调用返回时设置这个域。events域中请求的任何事件都可能在revents域中返回。合法的事件如下:
POLLIN 有数据可读。
POLLRDNORM 有普通数据可读。
POLLRDBAND 有优先数据可读。
POLLPRI 有紧迫数据可读。
POLLOUT 写数据不会导致阻塞。
POLLWRNORM 写普通数据不会导致阻塞。
POLLWRBAND 写优先数据不会导致阻塞。
POLLMSGSIGPOLL 消息可用。
此外,revents域中还可能返回下列事件:
POLLER 指定的文件描述符发生错误。
POLLHUP 指定的文件描述符挂起事件。
POLLNVAL 指定的文件描述符非法。
这些事件在events域中无意义,因为它们在合适的时候总是会从revents中返回。
*/
// linux14.04编译环境
// g++ poll.cpp -lpthread
// ./a.out
// 代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <poll.h>
#include <pthread.h>
int m_pipe[2];
pthread_t thread[2];
pthread_mutex_t mut;
void* interrupt(void *)
{
while(1) {
usleep(1000000);
printf("interrupt\n");
static const char dummy = 0;
int n;
do {
n = write(m_pipe[1], &dummy, 1);
} while ((n < 0) && (errno == EINTR));
printf("thread quit!\n");
return 0;// 如果没有return,则会一直循环,知道进程结束.
if (n < 0) {
printf("Error writing to pipe (%s)", strerror(n));
}
}
}
int main()
{
int ret = pipe(m_pipe);
printf("pipe %d %d \n", m_pipe[0], m_pipe[1]);
if (ret != 0) {
m_pipe[0] = -1;
m_pipe[1] = -1;
printf("log create pipe failed");
return -1;
}
struct pollfd readFds[2] = {};
// readFds[0].fd = m_dataFd;
// readFds[0].events = POLLIN;
readFds[1].fd = m_pipe[0];
readFds[1].events = POLLIN;
int temp;
memset(&thread, 0, sizeof(thread));
/*创建线程*/
if((temp = pthread_create(&thread[0], NULL, interrupt, NULL)) != 0)
printf("线程1创建失败!\n");
while(1) {
int ret = poll(readFds, 2, 100000);
if (0 > ret) {
printf("poll ret < 0, ret = %d", ret);
return -1;
}
if (readFds[1].revents & POLLIN) {
printf("interrupt by pipe\n");
char c;
int n;
do {
n = read(m_pipe[0], &c, 1);
printf("after read ret:%d, read value %d\n", n, c);
} while (n < 0 && errno == EINTR);
if (n < 0) {
printf("Error reading from pipe (%s)", strerror(errno));
}
printf("main quit thread\n");
return -1; //这里如果不return,主线程则不会退出,要注意子线程会不会退出.
// break; //用break,则子线程不会退出,如果子线程没有return操作,则会一直循环.
}
}
usleep(10000000);
printf("11111111111111111111");
return 0;
}
poll 阻塞的使用:
poll就是对描述符进行监听,和select类似,但是poll没有最大描述符的限制,并且poll的描述符使用之后不会被清空,而select每次使用之后都要重新设置.不过他俩作用是一样的,
进行阻塞操作.
通过调用poll之后,内核可以告诉我们是否可以读写操作.
pollfd结构体定义如下:
struct pollfd {
int fd; // 文件描述符
short events; // 等待的事件
short revents; // 实际发生了的事件
} ;
/*
每一个pollfd结构体指定了一个被监视的文件描述符,可以传递多个结构体,指示poll()监视多个文件描述符。每个结构体的events域是监视该文件描述符的事件掩码,由用户来设置这个域。revents域是文件描述符的操作结果事件掩码,内核在调用返回时设置这个域。events域中请求的任何事件都可能在revents域中返回。合法的事件如下:
POLLIN 有数据可读。
POLLRDNORM 有普通数据可读。
POLLRDBAND 有优先数据可读。
POLLPRI 有紧迫数据可读。
POLLOUT 写数据不会导致阻塞。
POLLWRNORM 写普通数据不会导致阻塞。
POLLWRBAND 写优先数据不会导致阻塞。
POLLMSGSIGPOLL 消息可用。
此外,revents域中还可能返回下列事件:
POLLER 指定的文件描述符发生错误。
POLLHUP 指定的文件描述符挂起事件。
POLLNVAL 指定的文件描述符非法。
这些事件在events域中无意义,因为它们在合适的时候总是会从revents中返回。
*/
// linux14.04编译环境
// g++ poll.cpp -lpthread
// ./a.out
// 代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <poll.h>
#include <pthread.h>
int m_pipe[2];
pthread_t thread[2];
pthread_mutex_t mut;
void* interrupt(void *)
{
while(1) {
usleep(1000000);
printf("interrupt\n");
static const char dummy = 0;
int n;
do {
n = write(m_pipe[1], &dummy, 1);
} while ((n < 0) && (errno == EINTR));
printf("thread quit!\n");
return 0;// 如果没有return,则会一直循环,知道进程结束.
if (n < 0) {
printf("Error writing to pipe (%s)", strerror(n));
}
}
}
int main()
{
int ret = pipe(m_pipe);
printf("pipe %d %d \n", m_pipe[0], m_pipe[1]);
if (ret != 0) {
m_pipe[0] = -1;
m_pipe[1] = -1;
printf("log create pipe failed");
return -1;
}
struct pollfd readFds[2] = {};
// readFds[0].fd = m_dataFd;
// readFds[0].events = POLLIN;
readFds[1].fd = m_pipe[0];
readFds[1].events = POLLIN;
int temp;
memset(&thread, 0, sizeof(thread));
/*创建线程*/
if((temp = pthread_create(&thread[0], NULL, interrupt, NULL)) != 0)
printf("线程1创建失败!\n");
while(1) {
int ret = poll(readFds, 2, 100000);
if (0 > ret) {
printf("poll ret < 0, ret = %d", ret);
return -1;
}
if (readFds[1].revents & POLLIN) {
printf("interrupt by pipe\n");
char c;
int n;
do {
n = read(m_pipe[0], &c, 1);
printf("after read ret:%d, read value %d\n", n, c);
} while (n < 0 && errno == EINTR);
if (n < 0) {
printf("Error reading from pipe (%s)", strerror(errno));
}
printf("main quit thread\n");
return -1; //这里如果不return,主线程则不会退出,要注意子线程会不会退出.
// break; //用break,则子线程不会退出,如果子线程没有return操作,则会一直循环.
}
}
usleep(10000000);
printf("11111111111111111111");
return 0;
}
更多推荐
已为社区贡献2条内容
所有评论(0)