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

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>
            欧美激情一区二区三区高清视频 | 最新69国产成人精品视频免费| 国产日韩欧美a| 亚洲欧美国产高清va在线播| 一二三四社区欧美黄| 99精品欧美一区二区蜜桃免费| 久久九九免费视频| 欧美一区二区高清在线观看| 中文日韩在线| 亚洲免费在线视频| 欧美综合二区| 欧美在线综合视频| 久久av一区二区三区漫画| 久久大综合网| 欧美三级日本三级少妇99| 国产精品免费区二区三区观看| 国内精品久久久久久| 亚洲激情一区二区三区| 欧美一区二区日韩一区二区| 午夜精品福利视频| 蜜臀久久99精品久久久久久9 | 午夜精品视频在线观看一区二区 | 久久综合伊人77777尤物| 亚洲精品视频在线观看网站 | 欧美日本高清一区| 国产欧美一区视频| 一本在线高清不卡dvd| 浪潮色综合久久天堂| 99热这里只有精品8| 亚洲综合成人婷婷小说| 欧美激情一区二区三区在线视频观看 | 欧美大秀在线观看| 国产午夜精品一区二区三区欧美 | 久久精品国产2020观看福利| 欧美三级在线| 亚洲一级片在线看| 99一区二区| 欧美另类在线观看| 亚洲国产精品一区二区久| 久久综合免费视频影院| 久久精品国产一区二区三区| 国产亚洲一区二区三区在线播放| 亚洲免费在线看| 午夜天堂精品久久久久| 狠狠色狠狠色综合日日小说| 亚洲嫩草精品久久| 亚洲视频www| 夜夜嗨av一区二区三区四季av| 久久九九热免费视频| 亚洲日本va午夜在线电影| 亚洲国产日韩一区| 国产精品久久久久9999| 久久久精品国产99久久精品芒果| 久久精品国产亚洲5555| 亚洲国产91| 亚洲美女在线观看| 欧美日韩免费看| 久久免费少妇高潮久久精品99| 欧美影院成年免费版| 亚洲电影第三页| 亚洲伦理在线| 好看不卡的中文字幕| 国产精品久久久久久久久搜平片 | 亚洲乱码精品一二三四区日韩在线| 欧美视频一区| 欧美www视频| 欧美视频一区二区| 欧美成人一区二区三区| 国产欧美大片| 午夜精品久久久久99热蜜桃导演| 在线观看日韩欧美| 欧美亚洲一区二区三区| 亚洲自拍偷拍一区| 免费观看日韩av| 久久亚洲春色中文字幕久久久| 欧美性开放视频| 亚洲黄色毛片| 国产亚洲精品久久久久动| 91久久精品国产91性色| 黄色欧美成人| 夜夜爽99久久国产综合精品女不卡 | 亚洲在线视频免费观看| 在线综合亚洲欧美在线视频| 免费成人av在线| 久久夜色精品国产亚洲aⅴ | 欧美成人性生活| 久久国产毛片| 在线观看av不卡| 免费成人在线视频网站| 狼狼综合久久久久综合网 | 亚洲在线黄色| 亚洲欧美韩国| 男女激情久久| 日韩视频在线播放| 欧美一区二区三区电影在线观看| 亚洲免费伊人电影在线观看av| 国产麻豆精品视频| 欧美成人精品激情在线观看| 91久久久久久| 久久久久久久久久久一区| 亚洲激情专区| 欧美日韩视频第一区| 欧美在线视频观看免费网站| 欧美xxx成人| 日韩视频中午一区| 国产精品一级| 欧美成人在线免费观看| 亚洲视频视频在线| 欧美激情一区二区三区不卡| 久久精品免费观看| 一区二区三区日韩在线观看 | 亚洲综合第一页| 国产欧美日韩一区| 欧美国产国产综合| 麻豆国产va免费精品高清在线| 日韩香蕉视频| 制服丝袜激情欧洲亚洲| 亚洲精品综合精品自拍| 欧美在线免费播放| 性欧美1819性猛交| 99综合视频| 中文在线一区| 亚洲欧美日本视频在线观看| 亚洲一区二区三区四区视频| 亚洲精品综合精品自拍| 最新亚洲视频| 免费看的黄色欧美网站| 欧美激情精品久久久六区热门| 亚洲一级黄色| 久久免费视频在线| 亚洲黄色三级| 午夜精品久久久久久久99热浪潮| 亚洲欧美影音先锋| 久久久久免费| 国产精品福利在线观看| 精品1区2区| 亚洲欧美另类中文字幕| 亚洲精选一区| 性色av一区二区三区红粉影视| 久久夜色精品亚洲噜噜国产mv| 欧美xart系列高清| 精品不卡一区| 欧美中文字幕在线| 一本色道久久综合| 欧美va天堂| 国内伊人久久久久久网站视频| 亚洲免费av观看| 久久久久在线| 欧美在线亚洲在线| 欧美精品在线观看一区二区| 极品少妇一区二区| 久久伊人亚洲| 麻豆国产精品va在线观看不卡| 亚洲精选久久| 欧美日韩精品一区视频| 亚洲日韩欧美视频| 亚洲第一精品在线| 欧美成人黑人xx视频免费观看| 伊人久久大香线| 久久岛国电影| 欧美一区国产在线| 国产午夜精品理论片a级大结局| 欧美伊人久久久久久午夜久久久久| 亚洲久色影视| 国产情人节一区| 欧美+日本+国产+在线a∨观看| 久久国内精品自在自线400部| 国内精品国产成人| 欧美另类videos死尸| 久久精品亚洲一区二区三区浴池| 亚洲欧美激情四射在线日 | 新片速递亚洲合集欧美合集| 国产亚洲日本欧美韩国| 欧美+日本+国产+在线a∨观看| 久久天天躁狠狠躁夜夜av| 亚洲久色影视| 欧美一二三区精品| 这里只有精品在线播放| 欧美一区免费视频| 欧美日本精品在线| 久久久久久一区二区三区| 免费日本视频一区| 久久精品一区| 欧美日韩三级一区二区| 久久视频在线视频| 国产精品免费电影| 亚洲黄色免费网站| 激情综合中文娱乐网| 先锋影院在线亚洲| 亚洲欧美日本日韩| 欧美日韩1区2区| 亚洲国内高清视频| 亚洲高清毛片| 免费成人黄色av| 欧美电影免费观看网站| 国内成+人亚洲| 久久免费少妇高潮久久精品99| 国产裸体写真av一区二区| 欧美一区二区视频在线观看2020 | 久久久久国产精品厨房|