亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費(fèi)注冊(cè) 查看新帖 |

Chinaunix

  平臺(tái) 論壇 博客 文庫(kù)
最近訪問(wèn)板塊 發(fā)新帖
查看: 1093 | 回復(fù): 0
打印 上一主題 下一主題

進(jìn)程間通信(八) [復(fù)制鏈接]

論壇徽章:
0
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報(bào)告]
發(fā)表于 2009-08-11 23:26 |只看該作者 |倒序?yàn)g覽
搜索數(shù)據(jù)庫(kù)
在CD關(guān)鍵字上的搜索比較復(fù)雜。函數(shù)的用戶希望一旦調(diào)用就啟動(dòng)一個(gè)搜索。我們?cè)诘?章通過(guò)將在第一次調(diào)用上的*first_call_ptr設(shè)置為
true并且函數(shù)返回第一個(gè)匹配結(jié)果來(lái)滿足這種需求。在接下來(lái)的搜索函數(shù)調(diào)用中,*first_call_ptr設(shè)置為false,從而會(huì)返回更多的匹
配,每次調(diào)用返回一個(gè)匹配結(jié)果。
現(xiàn)在我們已經(jīng)將程序分為兩個(gè)進(jìn)程,我們不能再允許搜索在服務(wù)器端一次處理一個(gè)實(shí)體,因?yàn)榱硪粋(gè)不同的客戶端也許會(huì)由服務(wù)器請(qǐng)求一個(gè)不同的搜索,而我們的搜
索仍在處理之中。我們不能使得服務(wù)器端為每一個(gè)客戶端單獨(dú)存儲(chǔ)搜索內(nèi)容(搜索已經(jīng)進(jìn)行到哪里),因?yàn)楫?dāng)一個(gè)用戶找到他們要找的CD關(guān)鍵值時(shí)或是客戶端出現(xiàn)
問(wèn)題,客戶端就可以簡(jiǎn)單的停止搜索。
我們或者可以改變搜索執(zhí)行的方式,或者是,正如我們?cè)谶@里所選擇的,在接口例程中隱藏復(fù)雜性。我們所做的就是使得服務(wù)器返回所有可能的搜索匹配,然后將他們存儲(chǔ)在一個(gè)臨時(shí)文件中直到客戶端請(qǐng)求他們。
試驗(yàn)--查找
1 這個(gè)函數(shù)看起更為復(fù)雜,因?yàn)樗{(diào)用我們會(huì)在下一節(jié)討論的三個(gè)管道函數(shù):send_mess_to_server,start_resp_from_server與read_resp_from_server。
cdc_entry search_cdc_entry(const char *cd_catalog_ptr, int *first_call_ptr)
{
    message_db_t mess_send;
    message_db_t mess_ret;
    static FILE *work_file = (FILE *)0;
    static int entries_matching = 0;
    cdc_entry ret_val;
    ret_val.catalog[0] = ‘\0’;
    if (!work_file && (*first_call_ptr == 0)) return(ret_val);
2 下面是搜索的第一個(gè)調(diào)用,在這里*first_call_ptr設(shè)置為true。為了防止我們忘記,立即將其設(shè)置為false。在這個(gè)函數(shù)中創(chuàng)建一個(gè)work_file并且初始化客戶端消息結(jié)構(gòu)。
if (*first_call_ptr) {
    *first_call_ptr = 0;
    if (work_file) fclose(work_file);
    work_file = tmpfile();
    if (!work_file) return(ret_val);
    mess_send.client_pid = mypid;
    mess_send.request = s_find_cdc_entry;
    strcpy(mess_send.cdc_entry_data.catalog, cd_catalog_ptr);
3 接下是一個(gè)三層的條件測(cè)試。如果消息成功的發(fā)送到服務(wù)器,客戶端會(huì)等待服務(wù)器的響應(yīng)。當(dāng)服務(wù)器的read操作成功,搜索匹配就會(huì)被記入work_file中,而相應(yīng)的entries_matching也會(huì)增加。
if (send_mess_to_server(mess_send)) {
    if (start_resp_from_server()) {
        while (read_resp_from_server(&mess_ret)) {
            if (mess_ret.response == r_success) {
       fwrite(&mess_ret.cdc_entry_data, sizeof(cdc_entry), 1, work_file);
                entries_matching++;
            } else {
                break;
            }
        } /* while */
    } else {
        fprintf(stderr, “Server not responding\n”);
    }
} else {
    fprintf(stderr, “Server not accepting requests\n”);
}
4 下面的測(cè)試檢測(cè)搜索是否成功。然后fseek調(diào)用會(huì)將work_file設(shè)置為數(shù)據(jù)將要寫(xiě)入的下一個(gè)位置。
if (entries_matching == 0) {
    fclose(work_file);
    work_file = (FILE *)0;
    return(ret_val);
}
(void)fseek(work_file, 0L, SEEK_SET);
5 如果這并不是第一次使用特定的搜索模式調(diào)用搜索函數(shù),下面的代碼會(huì)檢測(cè)是否還有余下的匹配。最后,下一個(gè)匹配項(xiàng)會(huì)被讀入ret_val結(jié)構(gòu)中。前面的檢測(cè)認(rèn)為存在一個(gè)匹配項(xiàng)。
  } else {
          /* not *first_call_ptr */
      if (entries_matching == 0) {
          fclose(work_file);
          work_file = (FILE *)0;
          return(ret_val);
      }
  }
  fread(&ret_val, sizeof(cdc_entry), 1, work_file);
  entries_matching—;
  return(ret_val);
}
服務(wù)器接口
就如客戶端有一個(gè)對(duì)app_ui.c程序的一個(gè)接口,服務(wù)器端也需要一個(gè)程序來(lái)控制(重命名的)cd_access.c,現(xiàn)在是cd_dbm.c。服務(wù)器的main函數(shù)如下。
試驗(yàn)--server.c
1 我們?cè)诔绦虻拈_(kāi)始處聲明了幾個(gè)全局變量,一個(gè)process_command函數(shù)原型,以及一個(gè)信號(hào)捕獲函數(shù)來(lái)保證一個(gè)干凈的退出。
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include “cd_data.h”
#include “cliserv.h”
int save_errno;
static int server_running = 1;
static void process_command(const message_db_t mess_command);
void catch_signals()
{
    server_running = 0;
}
2
現(xiàn)在我們來(lái)了解一下main函數(shù)。在檢測(cè)信號(hào)捕獲例程正確之后,程序檢測(cè)我們是否在命令行傳遞了一個(gè)-i選項(xiàng)。如果我們傳遞了,程序就會(huì)創(chuàng)建一個(gè)新的數(shù)據(jù)
庫(kù)。如果cd_dbm.c中的database_initialize例程失敗,就會(huì)顯示一個(gè)錯(cuò)誤消息。如果一切正常而且服務(wù)器正在運(yùn)行,由客戶端來(lái)的請(qǐng)
求就會(huì)被傳遞給process_command函數(shù),這個(gè)函數(shù)我們將會(huì)稍后介紹。
int main(int argc, char *argv[]) {
    struct sigaction new_action, old_action;
    message_db_t mess_command;
    int database_init_type = 0;
    new_action.sa_handler = catch_signals;
    sigemptyset(&new_action.sa_mask);
    new_action.sa_flags = 0;
    if ((sigaction(SIGINT, &new_action, &old_action) != 0) ||
        (sigaction(SIGHUP, &new_action, &old_action) != 0) ||
        (sigaction(SIGTERM, &new_action, &old_action) != 0)) {
        fprintf(stderr, “Server startup error, signal catching failed\n”);
        exit(EXIT_FAILURE);
    }
    if (argc > 1) {
        argv++;
        if (strncmp(“-i”, *argv, 2) == 0) database_init_type = 1;
    }
    if (!database_initialize(database_init_type)) {
                fprintf(stderr, “Server error:-\
                         could not initialize database\n”);
                exit(EXIT_FAILURE);
    }
    if (!server_starting()) exit(EXIT_FAILURE);
    while(server_running) {
        if (read_request_from_client(&mess_command)) {
            process_command(mess_command);
        } else {
            if(server_running) fprintf(stderr, “Server ended - can not \
                                        read pipe\n”);
          server_running = 0;
      }
  } /* while */
  server_ending();
  exit(EXIT_SUCCESS);
}
3 所有的客戶端消息都會(huì)被傳遞給process_command函數(shù),在那里他們會(huì)被傳遞給一個(gè)case語(yǔ)句,從而執(zhí)行cd_dbm.c中的正確調(diào)用。
static void process_command(const message_db_t comm)
{
    message_db_t resp;
    int first_time = 1;
    resp = comm; /* copy command back, then change resp as required */
    if (!start_resp_to_client(resp)) {
        fprintf(stderr, “Server Warning:-\
                 start_resp_to_client %d failed\n”, resp.client_pid);
        return;
    }
    resp.response = r_success;
    memset(resp.error_text, ‘\0’, sizeof(resp.error_text));
    save_errno = 0;
    switch(resp.request) {
        case s_create_new_database:
            if (!database_initialize(1)) resp.response = r_failure;
            break;
        case s_get_cdc_entry:
            resp.cdc_entry_data =
                           get_cdc_entry(comm.cdc_entry_data.catalog);
            break;
        case s_get_cdt_entry:
            resp.cdt_entry_data =
                           get_cdt_entry(comm.cdt_entry_data.catalog,
                                         comm.cdt_entry_data.track_no);
            break;
        case s_add_cdc_entry:
            if (!add_cdc_entry(comm.cdc_entry_data)) resp.response =
                           r_failure;
            break;
        case s_add_cdt_entry:
            if (!add_cdt_entry(comm.cdt_entry_data)) resp.response =
                           r_failure;
            break;
        case s_del_cdc_entry:
          if (!del_cdc_entry(comm.cdc_entry_data.catalog)) resp.response
                        = r_failure;
          break;
      case s_del_cdt_entry:
          if (!del_cdt_entry(comm.cdt_entry_data.catalog,
                comm.cdt_entry_data.track_no)) resp.response = r_failure;
          break;
      case s_find_cdc_entry:
          do {
              resp.cdc_entry_data =
                         search_cdc_entry(comm.cdc_entry_data.catalog,
                                           &first_time);
              if (resp.cdc_entry_data.catalog[0] != 0) {
                   resp.response = r_success;
                   if (!send_resp_to_client(resp)) {
                       fprintf(stderr, “Server Warning:-\
                           failed to respond to %d\n”, resp.client_pid);
                       break;
                   }
              } else {
                   resp.response = r_find_no_more;
              }
          } while (resp.response == r_success);
      break;
      default:
          resp.response = r_failure;
          break;
  } /* switch */
  sprintf(resp.error_text, “Command failed:\n\t%s\n”,
           strerror(save_errno));
  if (!send_resp_to_client(resp)) {
      fprintf(stderr, “Server Warning:-\
                failed to respond to %d\n”, resp.client_pid);
  }
  end_resp_to_client();
  return;
}
在我們了解實(shí)際的管道實(shí)現(xiàn)之前,讓我們來(lái)討論一下在客戶端與服務(wù)器進(jìn)程之間傳遞數(shù)據(jù)需要發(fā)生的事件序列。圖13-9顯示所啟動(dòng)的客戶端與服務(wù)器進(jìn)程以及在處理命令與響應(yīng)時(shí)雙方是如何循環(huán)的。
在這個(gè)實(shí)現(xiàn)中,形勢(shì)有一些困難,因?yàn)閷?duì)于一個(gè)搜索請(qǐng)求,客戶端向服務(wù)器傳遞一個(gè)單一命令,然后希望由服務(wù)器接收一個(gè)或多個(gè)響應(yīng)。這會(huì)導(dǎo)致其他額外的一些復(fù)雜性,主要在客戶端。
               
               
               

本文來(lái)自ChinaUnix博客,如果查看原文請(qǐng)點(diǎn):http://blog.chinaunix.net/u/19185/showart_2024894.html
您需要登錄后才可以回帖 登錄 | 注冊(cè)

本版積分規(guī)則 發(fā)表回復(fù)

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號(hào)-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號(hào):11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報(bào)專區(qū)
中國(guó)互聯(lián)網(wǎng)協(xié)會(huì)會(huì)員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過(guò)ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請(qǐng)注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP