تفاوت میان نسخه‌های «Kqueue»

۲٬۱۷۱ بایت اضافه‌شده ،  ۵ سال پیش
بدون خلاصه ویرایش
 
برخی از سیستم‌عامل‌های دیگر که تنها select(){{چر}} poll(){{چر}} را پشتیبانی می‌کنند هم در حال حاضر تعدادی راه حل جایگزین مشابه kqueue ارائه کرده‌اند که از جمله آنها می‌توان به [[epoll]] در [[لینوکس]] اشاره کرد. استفاده مستقیم از kquque می‌تواند باعث شود تا برنامه پورتابل بودن خود را از دست بدهد، چرا که بعضی از سیستم‌عامل‌ها از kqueue پشتیبانی نمی‌کنند. در عوض، می‌توان از رابط‌های آگاه‌سازی غیر وابسته به پلتفرم همانند [[libevent]] استفاده کرد، بدون اینکه تفاوت قابل ملاحظه‌ای در کارایی برنامه از دست برود.
 
== مثال ==
<source lang="c">
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/event.h>
#include <sys/time.h>
#include <errno.h>
void die(const char*);
int main(int argc, char *argv[])
{
int sockfd, nev, kq;
struct addrinfo hints, *res, *res0;
struct kevent change[2], event[2];
ssize_t nbytes;
char buf[BUFSIZ];
const char *cause = NULL;
if (3 != argc)
{
fprintf(stderr, "Usage: %s address port\n", argv[0]);
exit(EXIT_FAILURE);
}
(void)memset(&hints, '\0', sizeof(struct addrinfo));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
if (-1 == getaddrinfo(argv[1], argv[2], &hints, &res0))
die("getaddrinfo");
sockfd = -1;
for (res = res0; res; res = res->ai_next)
{
if (-1 == (sockfd = socket(res->ai_family, res->ai_socktype,
res->ai_protocol)))
{
cause = "socket";
continue;
}
if (-1 == connect(sockfd, res->ai_addr, res->ai_addrlen))
{
cause = "connect()";
close(sockfd);
continue;
}
break;
}
if (-1 == sockfd)
die(cause);
if (-1 == fcntl(sockfd, F_SETFL, O_NONBLOCK))
die("fcntl1()");
if (-1 == fcntl(STDIN_FILENO, F_SETFL, O_NONBLOCK))
die("fcntl()");
if (-1 == (kq = kqueue()))
die("kqueue()");
EV_SET(&change[0], STDIN_FILENO, EVFILT_READ, EV_ADD | EV_ENABLE,
0, 0, 0);
EV_SET(&change[1], sockfd, EVFILT_READ, EV_ADD | EV_ENABLE,
0, 0, 0);
for (;;)
{
if (-1 == (nev = kevent(kq, change, 2, event, 2, NULL)))
die("kevent()");
for (int i = 0; i < nev; i++)
{
if (event[i].ident == STDIN_FILENO)
{
fgets(buf, sizeof(buf), stdin);
nbytes = send(sockfd, buf, strlen(buf), 0);
if (-1 == nbytes)
if (EWOULDBLOCK != errno)
die("send()");
}
else
{
nbytes = recv(sockfd, buf, sizeof(buf), 0);
if (-1 == nbytes)
if (EWOULDBLOCK != errno)
die("recv()");
buf[nbytes] = '\0';
write(STDOUT_FILENO, buf, strlen(buf));
}
}
}
return 0;
}
void die(const char *str)
{
perror(str);
exit(EXIT_FAILURE);
}
</source>
 
== منابع ==