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

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>
            亚洲经典一区| 国产精品久久9| 亚洲高清三级视频| 另类综合日韩欧美亚洲| 久久免费视频网站| 麻豆成人av| 亚洲大胆av| 一本大道av伊人久久综合| 亚洲精品久久久久久下一站 | 亚洲精品国产精品国产自| 黑人巨大精品欧美一区二区| 一区免费观看| 99综合在线| 亚洲欧美清纯在线制服| 久久国产欧美日韩精品| 蜜臀va亚洲va欧美va天堂| 亚洲第一搞黄网站| 亚洲午夜久久久久久久久电影院| 先锋亚洲精品| 欧美福利在线| 国产午夜精品全部视频播放| 亚洲国产成人不卡| 裸体一区二区三区| 能在线观看的日韩av| 欧美亚洲尤物久久| 欧美诱惑福利视频| 一本色道久久综合狠狠躁的推荐| 国产一区二区| 激情欧美一区二区| 午夜精品久久久久影视| 国产色综合网| 一本色道久久综合亚洲精品婷婷| 欧美激情第8页| 夜夜嗨av一区二区三区网站四季av| 欧美一区二区视频免费观看| 欧美精品免费在线观看| 激情久久影院| 欧美一区二区三区免费在线看| 欧美福利在线观看| 欧美在线|欧美| 国产精品久久看| 亚洲另类在线视频| 久久午夜色播影院免费高清| 在线亚洲一区| 欧美日韩国产小视频在线观看| 在线观看久久av| 久久久久.com| 午夜久久久久久久久久一区二区| 亚洲第一页自拍| 亚洲欧洲日本国产| 亚洲免费av网站| 免费观看成人www动漫视频| 伊人久久婷婷色综合98网| 亚洲欧美国产高清va在线播| 国产精品成人免费视频| 99日韩精品| 看欧美日韩国产| 亚洲精品国产精品乱码不99| 久久精品72免费观看| 亚洲美女中文字幕| 久久网站免费| 欧美日韩免费| 国产欧美在线观看| 欧美日韩精品一区二区三区四区| 久久久午夜精品| 欧美成人免费视频| 欧美极品aⅴ影院| 欧美精品一区二区在线观看| 欧美日韩成人在线播放| 国产精品日本精品| 亚洲精品女av网站| 亚洲精品极品| 国产精品久久久久久久久久直播| 激情偷拍久久| 久久伊伊香蕉| 欧美激情精品久久久久久免费印度 | 亚洲欧美成人一区二区在线电影| 亚洲欧美日韩一区二区在线 | 一区二区亚洲精品| 99视频精品全国免费| 亚洲欧美国产另类| 久久久噜噜噜久久中文字幕色伊伊 | 蜜桃av噜噜一区二区三区| 亚洲精品1区| 欧美亚洲自偷自偷| 亚洲第一视频网站| 欧美一级午夜免费电影| 国产精品久久久久免费a∨大胸| 国产精品久久久91| 亚洲永久精品国产| 亚洲无人区一区| 91久久久亚洲精品| 亚洲国产经典视频| 在线精品在线| 亚洲精品小视频在线观看| 国产一区二区三区黄| 国产欧美日韩不卡| 久久成人国产| 免费成人小视频| 亚洲综合99| 欧美专区18| 夜久久久久久| 先锋a资源在线看亚洲| 亚洲国产合集| 亚洲自拍高清| 亚洲人成精品久久久久| 99精品欧美一区| 韩国av一区二区三区在线观看| 亚洲国产精品一区制服丝袜| 国产精品免费网站在线观看| 蜜桃精品一区二区三区| 欧美区在线播放| 久久五月激情| 国产精品亚洲一区二区三区在线| 欧美成人精品福利| 国产精品视频一二三| 亚洲国产成人av在线| 国产亚洲欧美日韩日本| 一本色道88久久加勒比精品 | 亚洲一区二区欧美日韩| 亚洲成人在线免费| 先锋影音国产精品| 亚洲一区欧美激情| 欧美激情中文不卡| 欧美不卡在线视频| 好看的亚洲午夜视频在线| 亚洲免费视频一区二区| 一本色道久久精品| 欧美黄免费看| 亚洲国产高清视频| 最新国产拍偷乱拍精品| 久久久欧美精品sm网站| 久久久久久久精| 国产视频亚洲| 欧美一级艳片视频免费观看| 午夜精品一区二区三区在线视 | 久久精品欧美日韩精品| 久久精品国产99国产精品澳门| 欧美天天在线| 99在线精品观看| 亚洲视频导航| 国产精品a久久久久| 9l国产精品久久久久麻豆| 一区二区三区蜜桃网| 欧美日韩人人澡狠狠躁视频| 中国女人久久久| 欧美日韩四区| 日韩午夜在线| 亚洲一区日韩在线| 国产精品videosex极品| 一区二区三区视频观看| 亚洲欧美一区二区三区在线| 欧美体内谢she精2性欧美| 一区二区三区日韩在线观看| 亚洲欧美日韩一区二区在线| 国产精品你懂的在线| 欧美与欧洲交xxxx免费观看| 欧美成人激情在线| 亚洲精品老司机| 欧美日韩免费观看中文| 亚洲欧美bt| 欧美激情第二页| 亚洲一区二区三区四区五区午夜| 国产精品一卡二卡| 久久视频这里只有精品| 亚洲精品国精品久久99热一| 亚洲在线1234| 在线电影一区| 欧美视频精品在线观看| 久久精品人人做人人爽| 亚洲日本一区二区三区| 欧美中文字幕在线观看| 亚洲精品综合| 国产专区精品视频| 欧美午夜美女看片| 美女任你摸久久| 亚洲欧美日韩精品在线| 亚洲高清在线视频| 欧美一区二区在线视频| 亚洲国产经典视频| 国产欧美日韩一区二区三区在线 | 欧美午夜精品电影| 久久精品国产综合| 中日韩男男gay无套| 欧美 日韩 国产在线| 亚洲欧美清纯在线制服| 亚洲精品自在在线观看| 精久久久久久| 国产欧美精品在线观看| 欧美日韩在线不卡| 欧美xxx成人| 久久久久国产精品一区三寸| 宅男噜噜噜66一区二区66| 欧美福利网址| 久久午夜视频| 久久天天躁狠狠躁夜夜爽蜜月| 欧美一级久久| 午夜久久福利| 欧美亚洲在线| 欧美一区久久|