原實例在APUE(第三版)17.2 UNIX域套接字
創(chuàng)新互聯(lián)堅持“要么做到,要么別承諾”的工作理念,服務(wù)領(lǐng)域包括:網(wǎng)站設(shè)計、
成都做網(wǎng)站、企業(yè)官網(wǎng)、英文網(wǎng)站、手機端網(wǎng)站、網(wǎng)站推廣等服務(wù),滿足客戶于互聯(lián)網(wǎng)時代的
婁底網(wǎng)站設(shè)計、移動媒體設(shè)計的需求,幫助企業(yè)找到有效的互聯(lián)網(wǎng)解決方案。努力成為您成熟可靠的網(wǎng)絡(luò)建設(shè)合作伙伴!
1、使用UNIX與套接字輪詢XSI消息隊列(poll版,原版)
#include "apue.h"
#include
#include
#include
#include
#define NQ 3 //隊列的數(shù)量
#define MAXMSZ 512 //消息的大長度
#define KEY 0x123 //消息隊列的第一個key值
struct threadinfo {
int qid;
int fd;
};
struct mymesg {
long mtype;
char mtext[MAXMSZ];
};
void *helper(void *arg)
{
int n;
struct mymesg m;
struct threadinfo *tip = arg;
for (;;) {
printf("helper qid %d, fd %d, tid %u\n", tip->qid, tip->fd, (unsigned)pthread_self());
memset(&m, 0, sizeof(m));
if ((n = msgrcv(tip->qid, &m, MAXMSZ, 0, MSG_NOERROR)) < 0) {
err_sys("msgrcv error");
}
if (write(tip->fd, m.mtext, n) < 0) {
err_sys("write error");
}
}
}
int main()
{
int i, n, err;
int fd[2];
int qid[NQ];
struct pollfd pfd[NQ];
struct threadinfo ti[NQ];
pthread_t tid[NQ];
char buf[MAXMSZ];
for (i = 0; i < NQ; ++i) {
if ((qid[i] = msgget((KEY+i), IPC_CREAT|0666)) < 0) { //創(chuàng)建一個新隊列
err_sys("msgget error");
}
printf("queue %d ID is %d\n", i, qid[i]);
if (socketpair(AF_UNIX, SOCK_DGRAM, 0, fd) < 0) { //創(chuàng)建UNXI域套接字(fd管道)
err_sys("socketpair error");
}
printf("fd[0]:%d\n", fd[0]);
printf("fd[1]:%d\n", fd[1]);
pfd[i].fd = fd[0];
pfd[i].events = POLLIN;
ti[i].qid = qid[i];
ti[i].fd = fd[1];
if ((err = pthread_create(&tid[i], NULL, helper, &ti[i])) != 0) { //創(chuàng)建線程
err_exit(err, "pthread_create error");
}
}
for (;;) {
if (poll(pfd, NQ, -1) < 0) { //等待事件發(fā)生
err_sys("poll error");
}
for (i = 0; i < NQ; ++i) {
//printf("i:%d\n", i);
if (pfd[i].revents & POLLIN) {
if ((n = read(pfd[i].fd, buf, sizeof(buf))) < 0) {
err_sys("read error");
}
buf[n] = 0;
printf("queue %d id %d, message %s\n", i, qid[i], buf);
}
}
}
exit(0);
}編譯命令:
gcc pollmsg.c -o pollmsg -lapue -lpthread -std=c992、使用UNIX與套接字輪詢XSI消息隊列(epoll版,改版)
#include "apue.h"
#include
#include
#include
#include
#define NQ 3 //隊列的數(shù)量
#define MAXMSZ 512 //消息的大長度
#define KEY 0x123 //消息隊列的第一個key值
#define FDSIZE 1000
#define EPOLLEVENTS 100
struct threadinfo {
int qid;
int fd;
};
struct mymesg {
long mtype;
char mtext[MAXMSZ];
};
void *helper(void *arg)
{
int n;
struct mymesg m;
struct threadinfo *tip = arg;
for (;;) {
printf("helper qid %d, fd %d, tid %u\n", tip->qid, tip->fd, (unsigned)pthread_self());
memset(&m, 0, sizeof(m));
if ((n = msgrcv(tip->qid, &m, MAXMSZ, 0, MSG_NOERROR)) < 0) {
err_sys("msgrcv error");
}
if (write(tip->fd, m.mtext, n) < 0) {
err_sys("write error");
}
}
}
int main()
{
int i, n, err;
int fd[2];
int qid[NQ];
int epollfd;
struct epoll_event events[EPOLLEVENTS];
struct threadinfo ti[NQ];
pthread_t tid[NQ];
char buf[MAXMSZ];
epollfd = epoll_create(FDSIZE); //創(chuàng)建epoll文件描述符
for (i = 0; i < NQ; ++i) {
if ((qid[i] = msgget((KEY+i), IPC_CREAT|0666)) < 0) { //創(chuàng)建一個新隊列
err_sys("msgget error");
}
printf("queue %d ID is %d\n", i, qid[i]);
if (socketpair(AF_UNIX, SOCK_DGRAM, 0, fd) < 0) { //創(chuàng)建UNXI域套接字(fd管道)
err_sys("socketpair error");
}
struct epoll_event ev;
ev.events = EPOLLIN;
ev.data.fd = fd[0];
epoll_ctl(epollfd, EPOLL_CTL_ADD, fd[0], &ev); //注冊fd[0]到epoll
ti[i].qid = qid[i];
ti[i].fd = fd[1];
if ((err = pthread_create(&tid[i], NULL, helper, &ti[i])) != 0) { //創(chuàng)建線程
err_exit(err, "pthread_create error");
}
}
for (;;) {
int occurred;
if ((occurred = epoll_wait(epollfd, events, EPOLLEVENTS, -1)) < 0) { //等待事件發(fā)生
err_sys("epoll error");
}
if (occurred == 0) {
err_sys("epoll timeout");
}
for (i = 0; i < occurred; ++i) {
if (events[i].events & EPOLLIN) {
if ((n = read(events[i].data.fd, buf, sizeof(buf))) < 0) {
err_sys("read error");
}
buf[n] = 0;
printf("main thread %u, message %s\n", (unsigned)pthread_self(), buf);
}
}
}
exit(0);
}編譯命令:
gcc epollmsg.c -o epollmsg -lapue -lpthread -std=c993、給XSI消息隊列發(fā)送消息(測試程序,原版)
#include "apue.h"
#include
#define MAXMSZ 512
struct mymesg {
long mtype;
char mtext[MAXMSZ];
};
int main(int argc, char *argv[])
{
key_t key;
long qid;
size_t nbytes;
struct mymesg m;
if (argc != 3) {
fprintf(stderr, "usage: sendmsg KEY message\n");
exit(1);
}
key = strtol(argv[1], NULL, 0);
//printf("key:0x%08X\n", (unsigned )key);
if ((qid = msgget(key, 0)) < 0) { //打開一個現(xiàn)有隊列
err_sys("can't open queue key %s", argv[1]);
}
memset(&m, 0, sizeof(m));
strncpy(m.mtext, argv[2], MAXMSZ - 1);
nbytes = strlen(m.mtext);
m.mtype = 1;
//printf("qid:%ld\n", qid);
if (msgsnd(qid, &m, nbytes, 0) < 0) { //發(fā)送消息給指定消息隊列
err_sys("can't send message");
}
exit(0);
}編譯命令:
gcc sendmsg.c -o sendmsg -lapue -std=c99相關(guān)閱讀:
1、select、poll、epoll之間的區(qū)別總結(jié)[整理]
2、poll函數(shù)的使用,原文
3、APUE讀書筆記
*** walker ***
另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)cdcxhl.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國服務(wù)器、虛擬主機、免備案服務(wù)器”等云主機租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務(wù)可用性高、性價比高”等特點與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場景需求。
網(wǎng)頁標(biāo)題:將poll程序改為epoll實現(xiàn)-創(chuàng)新互聯(lián)
鏈接地址:http://weahome.cn/article/cshgcj.html