青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

Just enjoy programming

#

linux RPC 測試(轉(zhuǎn)載)

轉(zhuǎn)自:
http://www.justwinit.cn/post/3960/


RPC是glibc提供的函數(shù)參數(shù)/返回值封裝服務(wù), 并將封裝結(jié)果通過網(wǎng)絡(luò)傳到服務(wù)器.
RPC服務(wù)端首先要啟動portmapper服務(wù).
測試一個簡單的RPC傳輸示例, 先定義一個模板文件test.x

program TESTPROG{
        version VERSION{
                int int_echo(int)=1;
                int get_str_len(string)=2;
                int add ( int, int ) = 3;
        }=1;
}=30000;
內(nèi)含3個函數(shù), 注意其中一個有2個參數(shù).
然后可以用rpcgen生成一個Makefile:

rpcgen -a -N test.x

這會生成Makefile, 客戶端和服務(wù)端的程序, 和函數(shù)示例.
我們手工修改一下Makefile

# This is a template Makefile generated by rpcgen
# Parameters
CLIENT = test_client
SERVER = test_server
SOURCES_CLNT.c =
SOURCES_CLNT.h =
SOURCES_SVC.c =
SOURCES_SVC.h =
SOURCES.x = test.x
TARGETS_SVC.c = test_svc.c test_server.c test_xdr.c
TARGETS_CLNT.c = test_clnt.c test_client.c test_xdr.c
TARGETS = test.h test_xdr.c test_clnt.c test_svc.c
OBJECTS_CLNT = $(SOURCES_CLNT.c:%.c=%.o) $(TARGETS_CLNT.c:%.c=%.o)
OBJECTS_SVC = $(SOURCES_SVC.c:%.c=%.o) $(TARGETS_SVC.c:%.c=%.o)
# Compiler flags
CFLAGS += -g -pipe
LDLIBS += -lnsl
RPCGENFLAGS = -N
# Targets
all : $(CLIENT) $(SERVER)
$(TARGETS) : $(SOURCES.x)
        rpcgen $(RPCGENFLAGS) $(SOURCES.x)
$(OBJECTS_CLNT) : $(SOURCES_CLNT.c) $(SOURCES_CLNT.h) $(TARGETS_CLNT.c)
$(OBJECTS_SVC) : $(SOURCES_SVC.c) $(SOURCES_SVC.h) $(TARGETS_SVC.c)
$(CLIENT) : $(OBJECTS_CLNT)
        $(LINK.c) -o $(CLIENT) $(OBJECTS_CLNT) $(LDLIBS)
$(SERVER) : $(OBJECTS_SVC)
        $(LINK.c) -o $(SERVER) $(OBJECTS_SVC) $(LDLIBS)
clean:
         $(RM) core $(TARGETS) $(OBJECTS_CLNT) $(OBJECTS_SVC) $(CLIENT) $(SERVER)

修改test_server.c服務(wù)端的處理函數(shù), 提供3種服務(wù):

/*
* This is sample code generated by rpcgen.
* These are only templates and you can use them
* as a guideline for developing your own functions.
*/
#include "test.h"
int *
int_echo_1_svc(int arg1,  struct svc_req *rqstp)
{
        static int  result;
        //echo.
        result=arg1;
        printf("[RPC1] source=%d, echo=%d\n", arg1, result);
        return &result;
}
int *
get_str_len_1_svc(char *arg1,  struct svc_req *rqstp)
{
        static int  result;
        //get strlen.
        result=strlen(arg1);
        printf("[PRC2] str=%s, len=%d\n", arg1, result);
        return &result;
}
int *
add_1_svc(int arg1, int arg2,  struct svc_req *rqstp)
{
        static int  result;
        result=arg1+arg2;
        printf("[RPC3] %d+%d=%d\n", arg1, arg2, result);
        return &result;
}

客戶端test_client.c, 調(diào)用這三種服務(wù):

/*
* This is sample code generated by rpcgen.
* These are only templates and you can use them
* as a guideline for developing your own functions.
*/
#include "test.h"
void
testprog_1(char *host)
{
        CLIENT *clnt;
        int  *result_1;
        int int_echo_1_arg1=55;
        int  *result_2;
        char *get_str_len_1_arg1="Hello, world";
        int  *result_3;
        int add_1_arg1=10;
        int add_1_arg2=20;
        clnt = clnt_create (host, TESTPROG, VERSION, "udp");
        if (clnt == NULL) {
                clnt_pcreateerror (host);
                exit (1);
        }
        result_1 = int_echo_1(int_echo_1_arg1, clnt);
        if (result_1 == (int *) NULL) {
                clnt_perror (clnt, "call failed");
        }
        else
                printf("[PRC1] echo %d, source %d\n", *result_1,
                        int_echo_1_arg1);
        result_2 = get_str_len_1(get_str_len_1_arg1, clnt);
        if (result_2 == (int *) NULL) {
                clnt_perror (clnt, "call failed");
        }
        else
                printf("[RPC2] return %d, should %d\n", *result_2,
                        strlen(get_str_len_1_arg1));
        result_3 = add_1(add_1_arg1, add_1_arg2, clnt);
        if (result_3 == (int *) NULL) {
                clnt_perror (clnt, "call failed");
        }
        else
                printf("[PRC3] %d+%d=%d\n", add_1_arg1, add_1_arg2,
                        *result_3);
        clnt_destroy (clnt);
}
OK, 可以調(diào)用make了.
生成可執(zhí)行程序test_server和test_client.
我們啟動./test_server, 用rpcinfo看看:

$rpcinfo -p 127.0.0.1
program vers proto port
100000 2 tcp 111 portmapper
30000 1 udp 36307
30000 1 tcp 34883
Bingo! 啟動成功.

再開個終端, 嘗試一下調(diào)用.

./test_client 127.0.0.1
[PRC1] echo 55, source 55
[RPC2] return 12, should 12
[PRC3] 10+20=30

正是我們期望的.

Add By:Jackxiang
make -f Makefile.test

posted @ 2011-08-07 16:44 周強(qiáng) 閱讀(1202) | 評論 (0)編輯 收藏

最近的我

   最近的我狀態(tài)不錯,睡眠也好了很多,每天7點半左右起床,每天看看資料,看看論文,編編程序,晚上10點半左右回到宿舍,洗個澡上上網(wǎng)就睡覺了,周末去圖書館看看書或者實驗室待著。這樣的生活挺好的,就是現(xiàn)在每天坐車有點累。現(xiàn)在的心態(tài)確實不錯,不再多想了,不再去想以后會去哪,以后該做什么,一切都隨緣吧,每天都盡量努力點,把能做的事給做好。
   最近的動車相撞確實挺讓人糾心的。單就技術(shù)方面我感覺我們的高鐵和動車還是有很大問題的,有點大躍進(jìn),買國外的技術(shù)然后自己改裝下,就說是處于世界領(lǐng)先水平了。技術(shù)的創(chuàng)新是需要長時間的積累的,我感覺我們目前最多只是個模仿者,更別談創(chuàng)新了。我感覺很多方面我們是缺少創(chuàng)新的,單就計算機(jī)方面,國內(nèi)最近炒得很熱的云計算,好像很多公司都在搞,看上去很創(chuàng)新,但我感覺是缺乏技術(shù)積累的,很多公司目前只是在用國外的開源軟件做做研究,到目前為止都沒有一個像亞馬遜,谷歌一樣的數(shù)據(jù)中心。

posted @ 2011-07-31 20:18 周強(qiáng) 閱讀(292) | 評論 (3)編輯 收藏

Nginx源碼分析-Epoll模塊(轉(zhuǎn)載)

轉(zhuǎn)載自:http://www.tbdata.org/archives/1296


Nginx源碼分析-Epoll模塊

3 comments 十二月 26th, 2010 | by yixiao in 高性能服務(wù)器

Linux平臺上,Nginx使用epoll完成事件驅(qū)動,實現(xiàn)高并發(fā);本文將不對epoll本身進(jìn)行介紹(網(wǎng)上一堆一堆的文章介紹epoll的原理及使用方法,甚至源碼分析等),僅看一下Nginx是如何使用epoll的。

Nginx在epoll模塊中定義了好幾個函數(shù),這些函數(shù)基本都是作為回調(diào)注冊到事件抽象層的對應(yīng)接口上,從而實現(xiàn)了事件驅(qū)動的具體化,我們看如下的一段代碼:

ngx_event_module_t  ngx_epoll_module_ctx = {
    &epoll_name,
    ngx_epoll_create_conf,               /* create configuration */
    ngx_epoll_init_conf,                 /* init configuration */
    {
        ngx_epoll_add_event,             /* add an event */
        ngx_epoll_del_event,             /* delete an event */
        ngx_epoll_add_event,             /* enable an event */
        ngx_epoll_del_event,             /* disable an event */
        ngx_epoll_add_connection,        /* add an connection */
        ngx_epoll_del_connection,        /* delete an connection */
        NULL,                            /* process the changes */
        ngx_epoll_process_events,        /* process the events */
        ngx_epoll_init,                  /* init the events */
        ngx_epoll_done,                  /* done the events */
    }
};


這段代碼就是epoll的相關(guān)函數(shù)注冊到事件抽象層,這里所謂的事件抽象層在前面的博文中有提過,就是Nginx為了方便支持和開發(fā)具體的I/O模型,從而實現(xiàn)的一層抽象。代碼后面的注釋將功能說明得很詳細(xì)了,本文就只重點關(guān)注ngx_epoll_init和ngx_epoll_process_events兩個函數(shù),其他幾個函數(shù)就暫且忽略了。

ngx_epoll_init主要是完成epoll的相關(guān)初始化工作,代碼分析如下:

static ngx_int_t
ngx_epoll_init(ngx_cycle_t *cycle, ngx_msec_t timer)
{
    ngx_epoll_conf_t  *epcf;
	/*取得epoll模塊的配置結(jié)構(gòu)*/
    epcf = ngx_event_get_conf(cycle->conf_ctx, ngx_epoll_module);
	/*ep是epoll模塊定義的一個全局變量,初始化為-1*/
    if (ep == -1) {
    	/*創(chuàng)一個epoll對象,容量為總連接數(shù)的一半*/
        ep = epoll_create(cycle->connection_n / 2);
        if (ep == -1) {
            ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
                          "epoll_create() failed");
            return NGX_ERROR;
        }
    }
	/*nevents也是epoll模塊定義的一個全局變量,初始化為0*/
    if (nevents events) {
        if (event_list) {
            ngx_free(event_list);
        }

		/*event_list存儲產(chǎn)生事件的數(shù)組*/
        event_list = ngx_alloc(sizeof(struct epoll_event) * epcf->events,
                               cycle->log);
        if (event_list == NULL) {
            return NGX_ERROR;
        }
    }
    nevents = epcf->events;
	/*初始化全局變量ngx_io, ngx_os_is定義為:
		ngx_os_io_t ngx_os_io = {
    		ngx_unix_recv,
    		ngx_readv_chain,
    		ngx_udp_unix_recv,
    		ngx_unix_send,
    		ngx_writev_chain,
    		0
		};(位于src/os/unix/ngx_posix_init.c)
	*/
    ngx_io = ngx_os_io;
	/*這里就是將epoll的具體接口函數(shù)注冊到事件抽象層接口ngx_event_actions上。
	具體是上文提到的ngx_epoll_module_ctx中封裝的如下幾個函數(shù)
        ngx_epoll_add_event,
        ngx_epoll_del_event,
        ngx_epoll_add_event,
        ngx_epoll_del_event,
        ngx_epoll_add_connection,
        ngx_epoll_del_connection,
        ngx_epoll_process_events,
        ngx_epoll_init,
        ngx_epoll_done,
	*/
    ngx_event_actions = ngx_epoll_module_ctx.actions;
#if (NGX_HAVE_CLEAR_EVENT)
	/*epoll將添加這個標(biāo)志,主要為了實現(xiàn)邊緣觸發(fā)*/
    ngx_event_flags = NGX_USE_CLEAR_EVENT
#else
	/*水平觸發(fā)*/
    ngx_event_flags = NGX_USE_LEVEL_EVENT
#endif
                      |NGX_USE_GREEDY_EVENT /*io的時候,直到EAGAIN為止*/
                      |NGX_USE_EPOLL_EVENT; /*epoll標(biāo)志*/
    return NGX_OK;
}

epoll初始化工作沒有想象中的復(fù)雜,和我們平時使用epoll都一樣,下面看ngx_epoll_process_events,這個函數(shù)主要用來完成事件的等待并處理。

static ngx_int_t
ngx_epoll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, ngx_uint_t flags)
{
    int                events;
    uint32_t           revents;
    ngx_int_t          instance, i;
    ngx_uint_t         level;
    ngx_err_t          err;
    ngx_log_t         *log;
    ngx_event_t       *rev, *wev, **queue;
    ngx_connection_t  *c;
	/*一開始就是等待事件,最長等待時間為timer;nginx為事件
	專門用紅黑樹維護(hù)了一個計時器。后續(xù)對這個timer單獨分析。
	*/
    events = epoll_wait(ep, event_list, (int) nevents, timer);
    if (events == -1) {
        err = ngx_errno;
    } else {
        err = 0;
    }
    if (flags & NGX_UPDATE_TIME || ngx_event_timer_alarm) {
        /*執(zhí)行一次時間更新, nginx將時間緩存到了一組全局變量中,方便程序高效的獲取事件。*/
        ngx_time_update();
    }
	/*處理wait錯誤*/
    if (err) {
        if (err == NGX_EINTR) {
            if (ngx_event_timer_alarm) {
                ngx_event_timer_alarm = 0;
                return NGX_OK;
            }
            level = NGX_LOG_INFO;
        } else {
            level = NGX_LOG_ALERT;
        }
        ngx_log_error(level, cycle->log, err, "epoll_wait() failed");
        return NGX_ERROR;
    }
	/*wait返回事件數(shù)0,可能是timeout返回,也可能是非timeout返回;非timeout返回則是error*/
    if (events == 0) {
        if (timer != NGX_TIMER_INFINITE) {
            return NGX_OK;
        }
        ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
                      "epoll_wait() returned no events without timeout");
        return NGX_ERROR;
    }
    log = cycle->log;
	/*for循環(huán)開始處理收到的所有事件*/
    for (i = 0; i read;
		。。。。。。。。。。。。。

		/*取得發(fā)生一個事件*/
        revents = event_list[i].events;

		/*記錄wait的錯誤返回狀態(tài)*/
        if (revents & (EPOLLERR|EPOLLHUP)) {
            ngx_log_debug2(NGX_LOG_DEBUG_EVENT, log, 0,
                           "epoll_wait() error on fd:%d ev:%04XD",
                           c->fd, revents);
        }
        if ((revents & (EPOLLERR|EPOLLHUP))
             && (revents & (EPOLLIN|EPOLLOUT)) == 0)
        {
            /*
             * if the error events were returned without EPOLLIN or EPOLLOUT,
             * then add these flags to handle the events at least in one
             * active handler
             */
            revents |= EPOLLIN|EPOLLOUT;
        }
		/*該事件是一個讀事件,并該連接上注冊的讀事件是active的*/
        if ((revents & EPOLLIN) && rev->active) {
            if ((flags & NGX_POST_THREAD_EVENTS) && !rev->accept) {
                rev->posted_ready = 1;
            } else {
                rev->ready = 1;
            }

			/*事件放入相應(yīng)的隊列中;關(guān)于此處的先入隊再處理,在前面的文章中已經(jīng)介紹過了。*/
            if (flags & NGX_POST_EVENTS) {
                queue = (ngx_event_t **) (rev->accept ?
                               &ngx_posted_accept_events : &ngx_posted_events);
                ngx_locked_post_event(rev, queue); /*入隊*/
            } else {
                rev->handler(rev);
            }
        }
        wev = c->write;
		/*發(fā)生的是一個寫事件,和讀事件完全一樣的邏輯過程*/
        if ((revents & EPOLLOUT) && wev->active) {
            if (flags & NGX_POST_THREAD_EVENTS) {
                wev->posted_ready = 1;
            } else {
                wev->ready = 1;
            }
			/*先入隊再處理*/
            if (flags & NGX_POST_EVENTS) {
                ngx_locked_post_event(wev, &ngx_posted_events);
            } else {
                wev->handler(wev);
            }
        }
    }
    return NGX_OK;
}

本文將關(guān)注的兩個epoll函數(shù)也就這么一點代碼了,但整個epoll還有添加事件和刪除事件等的相關(guān)函數(shù),代碼都很簡單,本文就不做具體的分析了。

posted @ 2011-07-10 00:54 周強(qiáng) 閱讀(958) | 評論 (0)編輯 收藏

linux 進(jìn)程間通信之消息傳遞

linux 進(jìn)程間通信中消息傳遞主要分為管道,F(xiàn)IFO,消息隊列
(1)管道
管道由pipe函數(shù)創(chuàng)建,提供一個單路(單向)數(shù)據(jù)流。pipe函數(shù)返回兩個文件描述符:fd[0]和fd[1]。前者打開來讀,后者打開來寫。管道沒有名字,所以只能由有親緣關(guān)系的進(jìn)程使用。盡管管道是由單個進(jìn)程創(chuàng)建的,它卻很少在單個進(jìn)程內(nèi)使用。管道的典型用途為兩個不同進(jìn)程(一個是父進(jìn)程,一個是子進(jìn)程)提供進(jìn)程間的通信手段。首先,由一個進(jìn)程(它將成為父進(jìn)程)創(chuàng)建一個管道后調(diào)用fork派生一個自身的副本。接著,父進(jìn)程關(guān)閉這個管道的讀出端,子進(jìn)程關(guān)閉同一管道的寫入端。或者父進(jìn)程關(guān)閉這個管道的寫入端,子進(jìn)程關(guān)閉同一管道的讀出端。這就在父子進(jìn)程間提供了一個單向數(shù)據(jù)流。

(2)FIFO
FIFO指代先進(jìn)先出(First in,First out),linux中的FIFO類似管道。它是一個單向(半雙工)數(shù)據(jù)流。不同于管道的是,每個FIFO有一個路徑名與之關(guān)聯(lián),從而允許無親緣關(guān)系的進(jìn)程訪問同一個FIFO。FIFO也稱為有名管道。FIFO由mkfifo函數(shù)創(chuàng)建。其中pathname是一個普通的Unix路徑名,它是該FIFO的名字。mkfifo 函數(shù)已隱含指定 O_CREAT|O_EXCL. 也就是說,它那么創(chuàng)建一個新的FIFO,要么返回一個EEXIST錯誤(如果所指定的名字的FIFO已經(jīng)存在)。如果不想希望創(chuàng)建一個新的FIFO,那就改為調(diào)用open而不是mkfifo.要打開一個已存在的FIFO或創(chuàng)建一個新的FIFO,應(yīng)先調(diào)用mkfifo,再檢查它是否返回EEXIST錯誤,若返回該錯誤則改為調(diào)用open.mkfifo 命令也能創(chuàng)建FIFO。可以從shell腳本或命令行中使用它。在創(chuàng)建出一個FIFO后,它必須或者打開來讀,或者打開來寫,所用的可以是open函數(shù),也可以是某個標(biāo)準(zhǔn)I/O打開函數(shù)。FIFO不能打開來既讀又寫,因為它是半雙工的。對管道或FIFO的write總是往末尾添加數(shù)據(jù),對它們的read則總是從開頭返回數(shù)據(jù)。如果對管道或FIFO調(diào)用lseek,那就返回ESPIPE錯誤。

(3)Posix 消息隊列
消息隊列可認(rèn)為是一個消息鏈表。有足夠?qū)憴?quán)限的線程可往隊列中放置消息,有足夠讀權(quán)限的線程可從隊列中取走消息。每個消息都是一個記錄,它由發(fā)送者賦予一個優(yōu)先級。在某個進(jìn)程往一個隊列寫入消息之前,并不需要另外某個進(jìn)程在該隊列上等待消息的到達(dá)。這跟管道和FIFO是相反的,對后者來說,除非讀出者已存在,否則先有寫入者是沒有意義的。一個進(jìn)程可以往某個隊列寫入一些消息,然后終止,再讓另外一個進(jìn)程在以后某個時刻讀出這些消息。消息隊列具有隨內(nèi)核的持續(xù)性,這跟管道和FIFO不一樣。Posix消息隊列和System V消息隊列。這兩組函數(shù)間存在許多相似性,但也有主要的區(qū)別
1. 對Posix消息隊列的讀總是返回最高優(yōu)先級的最早消息,對System V消息隊列的讀則可以返回任意指定優(yōu)先級的消息。
2.當(dāng)往一個空隊列放置一個消息時,Posix 消息隊列允許產(chǎn)生一個信號或啟動一個線程。System V消息隊列則不提供類似機(jī)制。

隊列中的每個消息具有如下屬性:
1.一個無符號整數(shù)優(yōu)先級(Posix)或一個長整數(shù)類型(System V).
2.消息的數(shù)據(jù)部分長度(可以為0).
3.數(shù)據(jù)本身(如果長度大于0)

函數(shù)接口
1. mqd_t mq_open(const char *name,int oflag,...)
mq_open函數(shù)創(chuàng)建一個新的消息隊列或打開一個已存在的消息隊列
2.int mq_close(mqd_t mqdes);
mq_close函數(shù)關(guān)閉一個消息隊列。
3.int mq_unlink(const char *name);
從系統(tǒng)中刪除用作第一個參數(shù)的某個name.
4. int mq_getattr(mqd_t mqdes,struct mq_attr *attr);
   int mq_setattr(mqd_t mqdes,const struct mq_attr *attr,struct mq_attr *oattr);
每個消息隊列有四個屬性,mq_getattr返回所有這些屬性,mq_setattr則設(shè)置其中某個屬性。
struct mq_attr{
   long mq_flags;
   long mq_maxmsg;
   long mq_msgsize;
   long mq_curmsgs;
};
5.int mq_send(mqd_t mqdes,const char *ptr,size_t len,unsigned int prio);
 int mq_receive(mqd_t mqdes,char *ptr,size_t len,unsigned int *priop);
mq_send函數(shù)往消息隊列中寫入消息,mq_receive函數(shù)從消息隊列中讀出消息。

6.int mq_notify(mqd_t mqdes,const struct sigevent *motification);
結(jié)構(gòu)體:
union sigval{
    int sival_int;
    void *sival_ptr;
};

struct sigevent
{
    int sigev_notify;
    int sigev_signo;
    union sigval sigev_value;
    void  (*sigev_notify_function)(union sigval);
    pthread_attr_t *sigev_notify_attributes;
};
mq_notify函數(shù)為指定隊列建立或刪除異步事件通知。一些普遍適用于該函數(shù)的若干規(guī)則
1).如果notification參數(shù)非空,那么當(dāng)前進(jìn)程希望在一個消息達(dá)到所指定的先前為空的隊列時得到通知。我們說"該進(jìn)程被注冊為接收該隊列的通知"。
2).如果notification參數(shù)為空指針,而且當(dāng)前進(jìn)程目前被注冊為接收所指定隊列的通知,那么已存在的注冊將被撤銷。
3).任意時刻只有一個進(jìn)程可以被注冊為接收某個給定隊列的通知。
4).當(dāng)有一個消息達(dá)到某個先前為空的隊列,而且已有一個進(jìn)程被注冊為接收該隊列的通知時,只有在沒有任何線程阻塞在該隊列的mq_receive調(diào)用中的前提下,通知才會發(fā)出。這就是說,在mq_receive調(diào)用中的阻塞比任何通知的注冊都優(yōu)先。
5).當(dāng)該通知被發(fā)送給它的注冊進(jìn)程時,其注冊即被撤銷。該進(jìn)程必須再次調(diào)用mq_notify以重新注冊(想要的話)。

參考:Unix進(jìn)程間通信

posted @ 2011-07-07 02:29 周強(qiáng) 閱讀(3054) | 評論 (3)編輯 收藏

近期計劃

     最近的思緒有點亂,離找工作只剩7,8,9三個月了,該是好好計劃下。
 (1)盡快把論文寫完
 (2)找工作前要要看完的書
unix三卷書(就剩unix進(jìn)程間通信),TCP/IP 詳解(卷一),c++編程思想2卷書,effective c++,STL源碼分析,設(shè)計模式,算法導(dǎo)論,編程之美,程序員面試寶典
(3)源碼閱讀  nginx 閱讀

posted @ 2011-07-06 12:37 周強(qiáng) 閱讀(350) | 評論 (4)編輯 收藏

     晚上獨自一個人走在校園里,感覺特別的安靜,我喜歡這種平靜的生活,可能是因為這么多年一個人習(xí)慣了,有時候更喜歡一個人靜靜地待著,不用去理會其他人,可以獨自地思考。我感覺我以前缺少一個勇敢的心,不敢去追求一些美好的事物,錯過了很多東西。很多事是沒有對錯的,只在于自己的選擇。既然是自己做的選擇就不應(yīng)該去后悔什么,或許當(dāng)初不這樣選擇我會變得更好,但至少現(xiàn)在的我應(yīng)該感謝當(dāng)初的選擇,因為當(dāng)初的選擇才有現(xiàn)在的自己。突然想到了大姐說的一個詞“自律”,我感覺我有時真得太過自律了,有時候真想去放縱自己,羨慕那些把人生當(dāng)游戲的人,人生得意須盡歡,但我卻做不到,因為我知道我身上有很多責(zé)任,有很多事情需要去做。
    上周打家里電話,我爸問我是不是要放暑假了,我能聽出來他們想讓我回家看看了,我也很想回家看看,但最近我真得很忙,估計是沒時間回去了,只能等到過年的時候再回去了。
    上周末去醫(yī)院,發(fā)現(xiàn)有些數(shù)字確實有點高了,可能是因為長時間的壓力與睡眠不好造成的,是時候該為自己減減壓了,現(xiàn)在想想我真有點杞人憂天,很多事情我都可以不去想的。現(xiàn)在開始要堅持跑步鍛煉身體,好好改善睡眠了。要學(xué)會平靜地面對一切,簡單點,淡定點,不是非要做的事就不去想了,船到橋頭自然直。
   

posted @ 2011-07-04 21:38 周強(qiáng) 閱讀(295) | 評論 (2)編輯 收藏

linux 進(jìn)程間通信綜述

linux進(jìn)程間通信主要分為以下4個領(lǐng)域
(1)消息傳遞(管道,F(xiàn)IFO,消息隊列)
(2)同步(互斥鎖,條件變量,讀寫鎖,信號量)
(3)共享內(nèi)存區(qū)(匿名共享內(nèi)存區(qū),有名共享內(nèi)存區(qū))
(4)過程調(diào)用(Solaris門,Sun RPC)


linux進(jìn)程間的信息共享可以分為
(1) 基于文件系統(tǒng)的共享
(2) 基于內(nèi)核的共享
(3) 基于共享內(nèi)存區(qū)的共享


IPC對象的持續(xù)性
(1)隨進(jìn)程間持續(xù)的IPC對象一直存在到打開著該對象的最后一個進(jìn)程關(guān)閉該對象的最后一個進(jìn)程關(guān)閉該對象為止。
(2)隨內(nèi)核持續(xù)的IPC對象一直存在到內(nèi)核重新自舉或顯式刪除該對象為止。
(3)隨文件系統(tǒng)持續(xù)的IPC對象一直存在到顯示刪除該對象為止。即使系統(tǒng)自舉了,該對象還是存在的。


IPC類型                                       持續(xù)性
管道                                           隨進(jìn)程
FIFO                                          隨進(jìn)程

Posix互斥鎖                                 隨進(jìn)程
Posix條件變量                              隨進(jìn)程
Posix讀寫鎖                                 隨進(jìn)程
fcntl記錄上鎖                                隨進(jìn)程

Posix消息隊列                              隨內(nèi)核
Posix有名信號量                           隨內(nèi)核
Posix基于內(nèi)存的信號量                   隨進(jìn)程
Posix共享內(nèi)存區(qū)                           隨內(nèi)核

System V消息隊列                        隨內(nèi)核
System V信號量                           隨內(nèi)核
System V共享內(nèi)存區(qū)                     隨內(nèi)核

TCP套接字                                  隨進(jìn)程
UDP套接字                                  隨進(jìn)程
Unix域套接字                               隨進(jìn)程






名字空間:
當(dāng)兩個或多個無親緣關(guān)系的進(jìn)程使用某種類型的IPC對象來彼此交換信息時,該IPC對象必須有一個某種形式的名字或者標(biāo)識符,這樣其中一個進(jìn)程(往往是服務(wù)器)可以創(chuàng)建該IPC對象,其余進(jìn)程則可以指定同一個IPC對象。

IPC類型                        用于打開或創(chuàng)建IPC的名字空間                IPC打開后的標(biāo)識
管道                                     沒有名字                                      描述符
FIFO                                    路徑名                                         描述符

Posix互斥鎖                          沒有名字                                      pthread_mutex_t指針
Posix條件變量                       沒有名字                                      pthread_cond_t指針
Posix讀寫鎖                          沒有名字                                      pthread_rwlock_t指針
fcntl記錄上鎖                        路徑名                                         描述符

Posix消息隊列                       Posix IPC名字                              mqd_t值
Posix有名信號量                    Posix IPC名字                              sem_t指針
Posix基于內(nèi)存的信號量            沒有名字                                     sem_t指針
Posix共享內(nèi)存區(qū)                    Posix IPC名字                              描述符


System V消息隊列                key_t鍵                                       System V IPC標(biāo)識符
System V 信號量                  key_t鍵                                       System V IPC標(biāo)識符
System V共享內(nèi)存區(qū)              key_t鍵                                      System V IPC 標(biāo)識符

門                                      路徑名                                         描述符
sun RPC                             程序/版本                                     RPC句柄

TCP套接字                            IP地址與TCP 端口                         描述符
UDP套接字                           IP地址與UDP端口                          描述符
Unix域套接字                        路徑名                                        描述符  

posted @ 2011-07-04 09:58 周強(qiáng) 閱讀(10911) | 評論 (3)編輯 收藏

   最近一直在下雨,有好幾次都被淋濕了,不過想想偶爾淋淋雨感覺也挺好的。我還是挺喜歡下雨的,可能跟我的性格有點關(guān)系,眼神中總有一絲的憂愁。記得小時候下雨的時候總喜歡坐在家門口的傻傻地看著雨。雨總能給我?guī)硪环N安靜的感覺,下雨天在實驗室看看書對于我來說可以算是一種享受,可以不去想一些煩心事,可以讓我浮躁的心靜下來。高中有空閑下來的時候喜歡讀會詩,雨巷是其中一首比較喜歡的詩。

雨巷

作者: 戴望舒

 
撐著油紙傘,獨自
彷徨在悠長、悠長
又寂寥的雨巷
我希望逢著
一個丁香一樣地
結(jié)著愁怨的姑娘
 
她是有
丁香一樣的顏色
丁香一樣的芬芳
丁香一樣的憂愁
在雨中哀怨
哀怨又彷徨
 
她彷徨在這寂寥的雨巷
撐著油紙傘
像我一樣
像我一樣地
默默彳亍著
寒漠、凄清,又惆悵
 
她默默地走近
走近,又投出
太息一般的眼光
她飄過
像夢一般地
像夢一般地凄婉迷茫
 
像夢中飄過
一枝丁香地
我身旁飄過這女郎
她靜默地遠(yuǎn)了、遠(yuǎn)了
到了頹圮的籬墻
走盡這雨巷
 
在雨的哀曲里
消了她的顏色
散了她的芬芳
消散了,甚至她的
太息般的眼光
丁香般的惆悵
 
撐著油紙傘,獨自
彷徨在悠長、悠長
又寂寥的雨巷
我希望飄過
一個丁香一樣地
結(jié)著愁怨的姑娘


posted @ 2011-06-30 17:12 周強(qiáng) 閱讀(331) | 評論 (5)編輯 收藏

linux 守護(hù)進(jìn)程編寫規(guī)則

linux 守護(hù)進(jìn)程編寫規(guī)則

(1)首先要做的是調(diào)用umask將文件模式創(chuàng)建屏蔽字設(shè)置為0.由繼承得來的文件模式創(chuàng)建屏蔽字可能會拒絕設(shè)置某些權(quán)限。
(2)調(diào)用fork,然后使父進(jìn)程退出(exit).這樣做實現(xiàn)了下面幾點:第一,如果該守護(hù)進(jìn)程是作為一條簡單shell命令啟動的,那么父進(jìn)程終止使得shell認(rèn)為這條命令已經(jīng)執(zhí)行完畢。第二,子進(jìn)程繼承了父進(jìn)程的進(jìn)程組ID,但具有一個新的進(jìn)程ID,這就保證了子進(jìn)程不是一個進(jìn)程組的組長進(jìn)程。這對于下面就要做的setsid調(diào)用是必要的前提條件。
(3)調(diào)用setsid以創(chuàng)建一個新會話,是調(diào)用進(jìn)程:(a)成為新會話的首進(jìn)程,(b)成為一個新進(jìn)程組的組長進(jìn)程,(c)沒有控制終端。在有些人建議在此時再次調(diào)用 fork,并是父進(jìn)程終止。第二個子進(jìn)程作為守護(hù)進(jìn)程繼續(xù)運行。這樣就保證了該守護(hù)進(jìn)程不是會話首進(jìn)程。
(4)將當(dāng)前工作目錄更改為根目錄。
(5)關(guān)閉不再需要的文件描述符。這使守護(hù)進(jìn)程不再持有從其父進(jìn)程繼承來的某些文件描述符。
(6)某些守護(hù)進(jìn)程打開/dev/null使其具有文件描述符0,1,2.這樣,任何一個試圖讀標(biāo)準(zhǔn)輸入,寫標(biāo)準(zhǔn)輸出或標(biāo)準(zhǔn)出錯的庫例程都不會產(chǎn)生任何效果。

參考:UNIX環(huán)境高級編程

posted @ 2011-06-29 21:50 周強(qiáng) 閱讀(2192) | 評論 (1)編輯 收藏

nginx源碼分析 ngx_palloc.h ngx_palloc.c

ngx_palloc.h 和 ngx_palloc.c主要用于nginx管理內(nèi)存池

#include <ngx_config.h>
#include <ngx_core.h>


/*
 * NGX_MAX_ALLOC_FROM_POOL should be (ngx_pagesize - 1), i.e. 4095 on x86.
 * On Windows NT it decreases a number of locked pages in a kernel.
 */
#define NGX_MAX_ALLOC_FROM_POOL  (ngx_pagesize - 1)
//內(nèi)存池默認(rèn)大小
#define NGX_DEFAULT_POOL_SIZE    (16 * 1024)

//#define ngx_align(d, a)     (((d) + (a - 1)) & ~(a - 1)) 將d向上取a的倍數(shù)。

#define NGX_POOL_ALIGNMENT       16
//內(nèi)存池的最小大小,為16的倍數(shù)
#define NGX_MIN_POOL_SIZE                                                     \
    ngx_align((sizeof(ngx_pool_t) + 2 * sizeof(ngx_pool_large_t)),            \
              NGX_POOL_ALIGNMENT)

//ngx_pool_cleanup_pt 為函數(shù)指針
typedef void (*ngx_pool_cleanup_pt)(void *data);

typedef struct ngx_pool_cleanup_s  ngx_pool_cleanup_t;
//這個結(jié)構(gòu)用來表示內(nèi)存池中的數(shù)據(jù)的清理handler
//handler表示清理函數(shù),data表示傳遞給清理函數(shù)的數(shù)據(jù),next表示下一個清理handler,
//也就是說當(dāng)destroy這個pool的時候會遍歷清理handler鏈表,然后調(diào)用handler.
struct ngx_pool_cleanup_s {
    ngx_pool_cleanup_pt   handler;
    void                 *data;
    ngx_pool_cleanup_t   *next;
};


typedef struct ngx_pool_large_s  ngx_pool_large_t;
//該結(jié)構(gòu)表示大塊內(nèi)存,這個結(jié)構(gòu)很簡單,就是一個指針指向下一塊large,一個alloc指向數(shù)據(jù)
struct ngx_pool_large_s {
    ngx_pool_large_t     *next;
    void                 *alloc;
};

//數(shù)據(jù)區(qū)的指針ngx_pool_data_t。其中l(wèi)ast表示當(dāng)前的數(shù)據(jù)區(qū)的已經(jīng)使用的數(shù)據(jù)的結(jié)尾。
//end表示當(dāng)前的內(nèi)存池的結(jié)尾。也就是說end-last就是內(nèi)存池未使用的大小。
typedef struct {
    u_char               *last;
    u_char               *end;
//指向下一塊內(nèi)存池
    ngx_pool_t           *next;
//申請該內(nèi)存池失敗的標(biāo)記
    ngx_uint_t            failed;
} ngx_pool_data_t;


struct ngx_pool_s {
    ngx_pool_data_t       d;
    size_t                max;
    ngx_pool_t           *current;
    ngx_chain_t          *chain;
    ngx_pool_large_t     *large;
    ngx_pool_cleanup_t   *cleanup;
    ngx_log_t            *log;
};


typedef struct {
    ngx_fd_t              fd;
    u_char               *name;
    ngx_log_t            *log;
} ngx_pool_cleanup_file_t;


void *ngx_alloc(size_t size, ngx_log_t *log);
void *ngx_calloc(size_t size, ngx_log_t *log);

ngx_pool_t *ngx_create_pool(size_t size, ngx_log_t *log);
void ngx_destroy_pool(ngx_pool_t *pool);
void ngx_reset_pool(ngx_pool_t *pool);

void *ngx_palloc(ngx_pool_t *pool, size_t size);
void *ngx_pnalloc(ngx_pool_t *pool, size_t size);
void *ngx_pcalloc(ngx_pool_t *pool, size_t size);
void *ngx_pmemalign(ngx_pool_t *pool, size_t size, size_t alignment);
ngx_int_t ngx_pfree(ngx_pool_t *pool, void *p);


ngx_pool_cleanup_t *ngx_pool_cleanup_add(ngx_pool_t *p, size_t size);
void ngx_pool_run_cleanup_file(ngx_pool_t *p, ngx_fd_t fd);
void ngx_pool_cleanup_file(void *data);
void ngx_pool_delete_file(void *data);


#endif /* _NGX_PALLOC_H_INCLUDED_ */

posted @ 2011-06-16 18:12 周強(qiáng) 閱讀(478) | 評論 (0)編輯 收藏

僅列出標(biāo)題
共6頁: 1 2 3 4 5 6 
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            国产精品午夜在线| 欧美伊人精品成人久久综合97| 亚洲美女毛片| 亚洲人成人77777线观看| 亚洲国产精品成人一区二区| 伊人精品成人久久综合软件| 国产婷婷色一区二区三区在线| 国产日韩欧美另类| 在线观看成人网| 亚洲毛片在线看| 亚洲一区黄色| 久久久99久久精品女同性| 久久午夜羞羞影院免费观看| 欧美国产三区| 亚洲一本大道在线| 久久天天躁狠狠躁夜夜爽蜜月| 你懂的视频一区二区| 欧美另类69精品久久久久9999| 国产精品久久久999| 伊人成人开心激情综合网| 日韩一级裸体免费视频| 欧美中文字幕视频在线观看| 国产欧美精品一区| 亚洲国产一区二区三区青草影视| 日韩午夜精品视频| 久久久99精品免费观看不卡| 亚洲精品午夜| 久久久噜噜噜久噜久久| 欧美图区在线视频| 悠悠资源网久久精品| 一区二区三区日韩欧美精品| 久久亚洲欧洲| 亚洲欧美日韩电影| 欧美美女bb生活片| 亚洲国产三级网| 久久久久久69| 亚洲一区二区免费| 欧美日韩精品高清| 亚洲人成亚洲人成在线观看图片| 久久精品国产精品亚洲| 99精品视频免费| 欧美sm重口味系列视频在线观看| 国产在线国偷精品产拍免费yy| 亚洲午夜一区二区三区| 最新精品在线| 欧美专区在线播放| 国产女人精品视频| 亚洲欧美自拍偷拍| 一区二区三区高清| 欧美三级网页| 亚洲视频一二| 日韩午夜中文字幕| 欧美日韩中文精品| 亚洲天堂av电影| 日韩一级黄色大片| 欧美日韩亚洲一区二区三区| 夜夜嗨av色综合久久久综合网| 欧美国产日韩精品免费观看| 久久人人精品| 亚洲电影在线看| 欧美成人午夜影院| 欧美成人免费小视频| 亚洲精品欧洲精品| 亚洲美女色禁图| 欧美日韩综合不卡| 亚洲性感美女99在线| 国产精品99久久久久久久女警| 欧美日韩国产综合视频在线观看 | 国产亚洲精品aa午夜观看| 亚洲一区二区三区乱码aⅴ蜜桃女| 亚洲七七久久综合桃花剧情介绍| 欧美成人精品不卡视频在线观看| 亚洲精品男同| 99这里只有精品| 国产精品免费一区二区三区观看 | 在线精品国精品国产尤物884a| 久久蜜桃香蕉精品一区二区三区| 久久久久欧美精品| 午夜欧美大尺度福利影院在线看| 国产日韩一区| 欧美ed2k| 欧美午夜片在线观看| 久久精品成人一区二区三区 | 久久人人97超碰国产公开结果| 亚洲国产精品一区在线观看不卡| 亚洲第一视频网站| 欧美先锋影音| 久久阴道视频| 欧美乱在线观看| 久久国产手机看片| 美女在线一区二区| 国产精品99久久久久久久久久久久 | 久久久www| 99热精品在线观看| 亚洲欧美日韩在线不卡| 亚洲国产mv| 亚洲一区二区三区高清 | 久久日韩粉嫩一区二区三区| 免费在线一区二区| 性欧美1819性猛交| 欧美wwwwww| 久久精品免费看| 欧美精品一区在线发布| 久久久福利视频| 欧美日韩亚洲一区二区三区在线观看| 久久国内精品视频| 欧美精品一区二区在线观看| 久久精品一二三| 欧美日韩小视频| 亚洲国产精品一区二区久| 国产日韩欧美一区二区| 亚洲人久久久| 1024国产精品| 欧美一区二区三区四区视频 | 亚洲中字在线| 欧美91大片| 老司机精品视频网站| 国产精品视频免费在线观看| 亚洲人成欧美中文字幕| ●精品国产综合乱码久久久久| 亚洲一区自拍| 亚洲一区二区三区精品在线观看 | 久久黄金**| 欧美资源在线观看| 国产精品久久久久久影视| 亚洲夫妻自拍| 亚洲国产激情| 久久综合一区| 欧美国产日韩亚洲一区| 在线精品一区二区| 久久蜜桃av一区精品变态类天堂| 久久久久久噜噜噜久久久精品| 亚洲欧美精品中文字幕在线| 在线一区视频| 欧美视频在线观看免费网址| 亚洲激情在线激情| 99v久久综合狠狠综合久久| 欧美成人一区二区三区片免费| 欧美成人首页| 日韩视频在线观看国产| 欧美久久婷婷综合色| 亚洲日韩成人| 亚洲在线成人精品| 国产伦精品一区二区三区照片91 | 亚洲美女免费视频| 亚洲私人黄色宅男| 国产精品二区在线观看| 亚洲综合丁香| 久久精品夜色噜噜亚洲aⅴ| 国产在线观看一区| 美女尤物久久精品| 亚洲欧洲日韩综合二区| 国产精品99久久久久久久久久久久 | 亚洲影院色在线观看免费| 国产精品极品美女粉嫩高清在线 | 最新亚洲电影| 欧美日韩国产在线看| 一区二区三区视频在线观看| 午夜精品久久久久久久久久久| 国产亚洲毛片| 欧美风情在线观看| 中文精品在线| 男男成人高潮片免费网站| 99视频超级精品| 国产日韩精品电影| 欧美成人蜜桃| 午夜亚洲性色福利视频| 欧美成人免费一级人片100| 一区二区三区欧美日韩| 国产欧美一区二区视频| 奶水喷射视频一区| 亚洲免费网址| 91久久极品少妇xxxxⅹ软件| 欧美一级一区| 99ri日韩精品视频| 激情成人综合网| 欧美视频在线观看免费网址| 久久久久国产精品一区三寸| 日韩一本二本av| 欧美aaaaaaaa牛牛影院| 午夜精品视频网站| 日韩午夜电影| 韩日欧美一区二区| 国产精品xxxxx| 欧美刺激性大交免费视频| 性色av一区二区三区红粉影视| 亚洲欧洲日韩女同| 欧美不卡在线视频| 欧美在线观看视频| 99精品黄色片免费大全| 亚洲高清av| 激情亚洲网站| 国产亚洲欧洲| 国产精品网站视频| 夜夜嗨一区二区| 亚洲激情国产| 欧美风情在线| 免费观看国产成人| 久久精品视频免费播放| 亚洲欧美中日韩|