Linux平臺上SQLite數據庫教程(二)——C語言API介紹

http://blog.csdn.net/u011192270/article/details/48086961

前言:本文將介紹幾個基本的SQLite3數據庫的C語言API接口,主要用到兩個文件:sqlite3.c、sqlite3.h。源碼地址:https://github.com/AnSwErYWJ/SQLite。

打開數據庫

1.原型:

int sqlite3_open(const char* filename,    /* 數據庫文件名, 必須為 UTF-8 格式 */sqlite3** ppDB            /* 輸出: SQLite 數據庫句柄 */
);;
  • 1
  • 2
  • 3
  • 4

2.說明:?
參數filename為指定打開的數據庫, sqlite3的結構指針?*ppDB?為數據庫連接句柄。如果數據庫被成功打開(和/或 創建), 函數返回?SQLITE_OK;否則返回一個錯誤碼, 可以通過* sqlite3_errmsg()* 查看錯誤原因.。出錯,則只可能是?SQLite?無法為?SQLite?對象分配內存空間, 此時將返回 NULL。

關閉數據庫

1.原型:

int sqlite3_close(sqlite3* pDB /* 由 sqlite3_open 或基相關的函數打開的 SQLite 對象句柄 */);
  • 1
  • 2
  • 3

2.說明:?
該函數用來關閉 sqlite3 對象。返回?SQLITE_OK?表示對象被成功關閉,以及所有相關的資源被成功回收。應用程序必須在關閉之前 “完成(finalize)” 所有的 “預編譯語句(prepared statements)”, 并且關閉所有的 “二進制句柄綁定(BLOB handle)”, 如果在關閉時還有未完成的預編譯語句或二進制句柄, 那么函數返回 SQLITE_BUSY(5)。

錯誤處理

原型1:

const char *sqlite3_errmsg(sqlite3* pDB    /* SQLite3 數據庫句柄 */
);
  • 1
  • 2
  • 3

說明1:?
該函數返回與pDB數據庫指針相關的錯誤信息,下次調用會覆蓋。

原型2:

int sqlite3_errcode(sqlite3* pDB    /* SQLite3 數據庫句柄 */
)
  • 1
  • 2
  • 3

說明2:?
該函數返回最近一次調用 sqlite3_ API時產生的錯誤碼。

示例一:

/*************************************************************************
    > File Name: example1.c
    > Author: AnSwEr
    > Mail: 1045837697@qq.com
    > Created Time: 2015年08月29日 星期六 14時17分21秒************************************************************************/#include<stdio.h>
#include<stdlib.h>
#include"sqlite3.h"int main(void)
{
    char *filename = "./first.db";
    sqlite3 *pDB = NULL;
    int ret = 0;    ret = sqlite3_open(filename,&pDB);
    if(ret != SQLITE_OK)
    {
        fprintf(stderr,"%s\n",sqlite3_errmsg(pDB));
        exit(EXIT_FAILURE);
    }    /*do something*/
    printf("open successfully!\n");    if(pDB != NULL)
    {
        sqlite3_close(pDB);
        pDB = NULL;
    }    printf("close successfully!\n");    return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37

示例一實現打開和關閉操作。

執行sql語句

原型:

int sqlite3_exec(sqlite3* pDB,        /* sqlite3句柄 */const char* sql,    /* 被執行的 SQL 語句 */int (*callback)(void*,int,char**,char**),  /* 執行/查詢回調函數 */void* pvoid,    /* 傳遞給回調函數的第一個參數 */char**errmsg    /* 錯誤輸出信息 */
);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

說明:?
當回調函數不為?NULL, 則它對每一個行查詢結果都會調用該回調函數;如果沒有回調函數被指定,?sqlite3_exec()?只是簡單地忽略查詢結果。?
如果回調函數返回非零,sqlite3_exec()?立即中斷查詢,并且不再執行后續的?SQL?語句,也不再調用回調函數,?sqlite3_exec()?將返回?SQLITE_ABORT?結束執行。?
當發生錯誤時, 執行將中斷。如果?errmsg?參數不為空,錯誤信息將會被寫入(errmsg?由?sqlite3_malloc()?分配內存空間,由sqlite3_free()?釋放該內存空間)。如果?errmsg?參數不為?NULL, 并且沒有錯誤發生, errmsg 被設置為?NULL。?
通常情況下callbackselect操作中會使用到,如果不需要回調函數。第三第四個參數設為NULL

回調函數原型:

int callback(void *params,  /*params是sqlite3_exec傳入的第四個參數*/int column_size,  /*column_size是結果字段的個數*/char **column_value,  /*column_value是返回記錄的一位字符數組指針*/char **column_name  /*column_name是結果字段的名稱*/
);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

示例二

/*************************************************************************> File Name: example2.c> Author: AnSwEr> Mail: 1045837697@qq.com> Created Time: 2015年08月29日 星期六 20時11分06秒************************************************************************//** 查詢數據庫*/
#include<stdio.h>
#include<stdlib.h>
#include"sqlite3.h"static print_info(void *params,int column_size,char **column_value,char **column_name)
{int i;for(i=0;i<column_size;i++)printf("\t%s",column_value[i]);printf("\n");return 0;
}int main(void)
{char *filename = "./first.db";sqlite3 *pDB = NULL;int ret = 0;/*open*/ret = sqlite3_open(filename,&pDB);if(ret != SQLITE_OK){fprintf(stderr,"%s\n",sqlite3_errmsg(pDB));exit(EXIT_FAILURE);}/*select*/char *errmsg = 0;ret = sqlite3_exec(pDB,"select * from stutable",print_info,NULL,&errmsg);if(ret != SQLITE_OK)fprintf(stderr,"select error:%s\n",errmsg);sqlite3_free(errmsg);/*close*/if(pDB != NULL){sqlite3_close(pDB);pDB = NULL;}return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56

示例二執行使用回調函數的select語句。此外,還有不使用回調函數的select語句(使用sqlite3_get_table,此函數是sqlite3_exec的包裝)。 不過個人感覺還是使用回調函數好,這樣代碼可看性強,更整潔。

sqlite3_get_table原型:

int sqlite3_get_table(sqlite3 *db,          /* An open database */const char *zSql,     /* SQL to be evaluated */char ***pazResult,    /* Results of the query */int *pnRow,           /* Number of result rows written here */int *pnColumn,        /* Number of result columns written here */char **pzErrmsg       /* Error msg written here */
);
void sqlite3_free_table(char **result);/*
db是sqlite3的句柄
zSql是要執行的sql語句
pazResult是執行查詢操作的返回結果集
pnRow是記錄的行數
pnColumn是記錄的字段個數
pzErrmsg是錯誤信息pazResult是一個(pnRow+1)*pnColumn結果集的字符串數組,其中前pnColumn個結果是字段的名稱,后pnRow行記錄是真實的字段值,如果某個字段為空,則對應值為NULL。
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

這里貼一段網上查到的不使用回調函數的select示例:

char **dbresult; int j,nrow,ncolumn,index;
//select tableret = sqlite3_get_table(db,"select * from t",&dbresult,&nrow,&ncolumn,&errmsg);if(ret == SQLITE_OK){printf("query %i records.\n",nrow);index=ncolumn;for(i=0;i<nrow;i++){printf("[%2i]",i);for(j=0;j<ncolumn;j++){printf(" %s",dbresult[index]);index++;}printf("\n");}}sqlite3_free_table(dbresult);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

示例三

/*************************************************************************> File Name: example3.c> Author: AnSwEr> Mail: 1045837697@qq.com> Created Time: 2015年08月29日 星期六 20時44分10秒************************************************************************//** 表的創建與刪除,數據的插入,更新與刪除。*/#include<stdio.h>
#include<stdlib.h>
#include"sqlite3.h"static print_info(void *params,int column_size,char **column_value,char **column_name)
{int i;for(i=0;i<column_size;i++)printf("\t%s",column_value[i]);printf("\n");return 0;
}int main(void)
{char *filename = "./first.db";sqlite3 *pDB = NULL;int ret = 0;/*open*/ret = sqlite3_open(filename,&pDB);if(ret != SQLITE_OK){fprintf(stderr,"%s\n",sqlite3_errmsg(pDB));exit(EXIT_FAILURE);}/*創建表*/const char *create_table = "create table t(id int primary key,name vachar(128))";char *errmsg = 0;ret = sqlite3_exec(pDB,create_table,NULL,NULL,&errmsg);if(ret != SQLITE_OK)fprintf(stderr,"create table error:%s\n",errmsg);sqlite3_free(errmsg);/*插入數據*/const char *insert_data = "insert into t(id,name) values(1,'answer')";ret = sqlite3_exec(pDB,insert_data,NULL,NULL,&errmsg);if(ret != SQLITE_OK)fprintf(stderr,"insert data error:%s\n",errmsg);/*查詢表中數據*/ret = sqlite3_exec(pDB,"select * from t",print_info,NULL,&errmsg);if(ret != SQLITE_OK)fprintf(stderr,"select error:%s\n",errmsg);printf("\n");/*更新表中數據*/const char *update_data = "update t set name='jack' where id=1";ret = sqlite3_exec(pDB,update_data,NULL,NULL,&errmsg);if(ret != SQLITE_OK)fprintf(stderr,"update_data error:%s\n",errmsg);/*查詢表中數據*/ret = sqlite3_exec(pDB,"select * from t",print_info,NULL,&errmsg);if(ret != SQLITE_OK)fprintf(stderr,"select error:%s\n",errmsg);printf("\n");/*刪除數據*/const char *delete_data = "delete from t where id = 1";ret = sqlite3_exec(pDB,delete_data,NULL,NULL,&errmsg);if(ret != SQLITE_OK)fprintf(stderr,"delete data error:%s\n",errmsg);/*查詢受上次操作影響的記錄數*/printf("delete data records:%i\n",sqlite3_changes(pDB));printf("\n");/*刪除表*/const char *drop_table = "drop table if exists t";ret = sqlite3_exec(pDB,drop_table,NULL,NULL,&errmsg);if(ret != SQLITE_OK)fprintf(stderr,"drop table error:%s\n",errmsg);/*close*/if(pDB != NULL){sqlite3_close(pDB);pDB = NULL;}return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98

示例三演示創建\刪除表,數據的插入、更新與刪除。

預編譯操作

注意:sqlite3_exec中已經封裝了預編譯操作,直接使用即可,預編譯操作只需稍作了解。

網上查了很多sqlite的預編譯操作的例子,比較復雜,大致可以分為以下幾個步驟:?
1. 通過sqlite3_prepare創建一個sqlite3_stmt對象?
2. 通過sqlite3_bind_*()綁定預編譯字段的值?
3. 通過sqlite3_step()執行SQL語句?
4. 通過sqlite3_reset()重置預編譯語句,重復操作2多次?
5. 通過sqlite3_finalize()銷毀資源

下面依次來看看這些函數。

sqlite3_prepare原型:

int sqlite3_prepare(sqlite3* pDB,            /* 成功打開的數據庫句柄 */const char* sql,        /* UTF8編碼的 SQL 語句 */int nbytes,                /* 參數 sql 的字節數, 包含 '\0' */sqlite3_stmt** ppStmt,    /* 輸出:預編譯語句句柄 */const char** pszTail    /* 輸出:指向 sql 語句中未使用的部分 */
);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

說明:?
如果nbytes小于0,?sql?語句則以第一個 ‘\0’終結。如果它非負,,則為讀取的最大長度.。當nbytes?大于 0 時,則讀取指定長度,如果’\0’先被讀到,則以’\0’結束。如果用戶知道被傳入的 sql 語句是以 ‘\0’ 結尾的,那么有一個更好的做法是:把nbytes的值設為該字符串的長度(包含’\0’),這樣可以避免 SQLite 復制該字符串的一份拷貝, 以提高程序的效率。?
如果?pszTail?不為 NULL, 則?*pszTail?指向?sql?中第一個被傳入的 SQL 語句的結尾。該函數只編譯?sql?的第一個語句, 所以 *pszTail 指向的內容則是未被編譯的。?
*ppStmt?指向一條可以被?sqlie3_step()?函數使用的預編譯語句.。如果有錯誤發生,?pszStmt 的值為*NULL。?
調用者應該使用?sqlite3_finalize()?刪掉被預編譯的語句。?
如果函數成功, 返回?SQLITE_OK, 否則返回一個錯誤碼。

sqlite3_bind_*有多種形式,分別對應不同的數據類型:

int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*));
int sqlite3_bind_double(sqlite3_stmt*, int, double);
int sqlite3_bind_int(sqlite3_stmt*, int, int);
int sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64);
int sqlite3_bind_null(sqlite3_stmt*, int);
int sqlite3_bind_text(sqlite3_stmt*, int, const char*, int n, void(*)(void*));
int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*));
int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*);
int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

預編譯SQL語句中可以包含如下幾種形式:

?
?NNN
:VVV
@VVV
$VVV
  • 1
  • 2
  • 3
  • 4
  • 5

NNN代表數字,VVV代表字符串.?
如果是?或者?NNN,那么可以直接sqlite3_bind_*()進行操作,如果是字符串,還需要通過sqlite3_bind_parameter_index()獲取對應的index,然后再調用sqlite3_bind_*()操作。這通常用于構造不定條件的SQL語句(動態SQL語句)。

int sqlite3_step原型:

int sqlite3_step(sqlite3_stmt* ppStmt    /* 一條被預編譯的 sql 語句 */
);
  • 1
  • 2
  • 3

說明:?
當一條語句被 sqlite3_prepare() 或其相關的函數預編譯后, sqlite3_step() 必須被調用一次或多次來評估該預編譯語句。?
該函數的詳細行為依賴于由 sqlite3_prepare()(或其相關的函數) 產生的是一條怎樣的預編譯語句。

返回值:?
SQLITE_BUSY:忙碌. 數據庫引擎無法鎖定數據去完成其工作。但可以多次嘗試。?
SQLITE_DONE:完成. sql 語句已經被成功地執行。在調用 sqlite_reset() 之前, 當前預編譯的語句不應該被 sqlite3_step() 再次調用。?
SQLITE_ROW:查詢時產生了結果。此時可以通過相關的”數據訪問函數(column access functions)”來取得數據. sqlite3_step() 的再一次調用將取得下一條查詢結果。?
SQLITE_ERROR:發生了錯誤。 此時可以通過 sqlite3_errmmsg() 取得相關的錯誤信息. sqlite3_step() 不能被再次調用。?
SQLITE_MISUSE:不正確的庫的使用. 該函數使用不當。

sqlite3_finalize原型:

int sqlite3_finalize(sqlite3_stmt* pStmt    /* 被預編譯的語句 */
);
  • 1
  • 2
  • 3

說明:?
該函數用來刪除一條被預編譯的 sql 語句。

預編譯實現代碼:

    int i = 0;sqlite3_stmt *stmt;char ca[255];//預編譯操作sqlite3_prepare_v2(db,"insert into t(id,msg) values(?,?)",-1,&stmt,0);for(i=10;i<20;i++){sprintf(ca,"HELLO#%i",i);sqlite3_bind_int(stmt,1,i);sqlite3_bind_text(stmt,2,ca,strlen(ca),NULL);sqlite3_step(stmt);sqlite3_reset(stmt);}sqlite3_finalize(stmt);stmt = NULL;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

總結

上文列出的是一些最基本精簡的C語言API,sqlite為C語言一共提供了200多個API。不過,上述這些API對一般的開發者而言已經足夠了,如果你還有更多的需求,那就請查閱前言中給出的源代碼文件(sqlite3.c,sqlite3.h)。

反饋與建議

  • 微博:@AnSwEr不是答案
  • github:AnSwErYWJ
  • 博客:AnSwEr不是答案的專欄

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/384234.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/384234.shtml
英文地址,請注明出處:http://en.pswp.cn/news/384234.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

epoll非阻塞IO

設置connfd套接字為非阻塞 flag fcntl(connfd, F_GETFL); flag | O_NONBLOCK; fcntl(connfd, F_SETFL, flag); 轉載于:https://www.cnblogs.com/lr1402585172/p/10758740.html

小白創建網站的曲折之路

小白創建網站的曲折之路 在虛擬機上創建網站 顧名思義&#xff0c;首先要有一個虛擬機。在網上百度一下后&#xff0c;我發現大家都在說使用一種叫做VMware Workstation的軟件進行虛擬機的構建 在這位好心人的幫助下我找到了Vmware Workstation的下載資源&#xff0c;并成功下…

Ubuntu 14.04數據庫服務器--mysql的安裝和配置

https://jingyan.baidu.com/article/425e69e6bbc6c7be14fc1640.html mysql是Oracle公司的一種開放源代碼的關系型數據庫管理系統&#xff0c;被廣泛應用于各中小網站&#xff0c;是一種跨平臺的數據庫管理系統&#xff0c;現在介紹一下如何在Ubuntu 14.04上安裝和配置mysql 工具…

javavbean

一、什么是javabeanJavaBean是一個遵循特定寫法的Java類&#xff0c;它通常具有如下特點&#xff1a;這個Java類必須具有一個無參的構造函數屬性必須私有化。私有化的屬性必須通過public類型的方法暴露給其它程序&#xff0c;并且方法的命名也必須遵守一定的命名規范。JavaBean…

Centos7下搭建LAMP環境,安裝wordpress(不會生產博客,只是一名博客搬運工)(菜鳥)

1.搭建MySQL數據庫 安裝MariaDB yum install mariadb-server -y 啟動MySQL服務 emctl start mariadb #啟動服務 emtcl enable marriadb#設置開機服務 設置MySQL賬戶和root密碼 mysqladmin -u root password ******* 2.安裝Apache服務 安裝Apache yum install httpd -y 啟動A…

(C語言版)棧和隊列(二)——實現順序存儲棧和順序存儲隊列的相關操作

http://blog.csdn.net/fisherwan/article/details/21479649 棧和隊列都有兩種實現方式&#xff0c;一種在之前已經寫過了&#xff0c;是鏈式存儲形式&#xff0c;另一種是順序存儲形式。也就是這里所寫的用數組的形式實現&#xff0c;和鏈式存儲形式相比&#xff0c;有幾個不同…

算法學習——貪心篇

貪心選擇是指應用同一規則&#xff0c;將原問題變為一個相似但是規模更小的問題&#xff0c;而后的每一步都是當前看起來最佳的選擇&#xff0c;且這種選擇只依賴于已做出的選擇&#xff0c;不依賴于未作出的選擇。 貪心算法說起來容易&#xff0c;操作起來卻經常有點玄學。&am…

使用基本MVC2模式創建新聞網站

轉載于:https://www.cnblogs.com/lr1402585172/p/10885084.html

棧(Stack),輕松解決數制轉換和括號匹配問題!

http://data.biancheng.net/view/9.html 棧&#xff0c;線性表的一種特殊的存儲結構。與學習過的線性表的不同之處在于棧只能從表的固定一端對數據進行插入和刪除操作&#xff0c;另一端是封死的。 圖1 棧結構示意圖由于棧只有一邊開口存取數據&#xff0c;稱開口的那一端為“…

第一章 TCP/IP協議族

一、協議族體系結構 TCP/IP協議族分為四層協議系統&#xff0c;自底向下分別為數據鏈路層、網絡層、傳輸層、應用層。 數據鏈路層常用ARP&#xff08;地址解析協議&#xff09;和RARP&#xff08;逆地址解析協議&#xff09;。在網絡層使用IP尋址&#xff0c;而在數據鏈路層使用…

二分(三分)+快速冪

之前學習的二分&#xff0c;現在感覺突然理解許多&#xff0c;補一下總結 首先&#xff0c;二分能夠解決什么樣的問題呢&#xff0c;個人認為&#xff0c;二分能夠快速解決已經知道答案范圍&#xff08;線性&#xff09;但是不知道確切答案的問題&#xff0c;例如在一個有序序列…

pthread_cleanup_push與pthread_cleanup_pop的目的 作用

http://blog.csdn.net/slj_win/article/details/7267483 首先你必須知道pthread_cleanup_push與pthread_cleanup_pop的目的(作用)是什么。 比如thread1: 執行 pthread_mutex_lock(&mutex); //一些會阻塞程序運行的調用&#xff0c;比如套接字的accept&#xff0c;等待客…

動態規劃淺談

接觸動態規劃這么久了&#xff0c;簡單談一下自己對動態規劃的理解。 動態規劃名字聽起來好像比比較高大上&#xff0c;可是事實上&#xff0c;人家就是比較高大上。&#xff08;抖個機靈&#xff09; 剛開始接觸動態規劃的時候覺得好可怕&#xff0c;這么復雜的問題我怎么能想…

Linux多線程——使用信號量同步線程

http://blog.csdn.net/ljianhui/article/details/10813469/ 信號量、同步這些名詞在進程間通信時就已經說過&#xff0c;在這里它們的意思是相同的&#xff0c;只不過是同步的對象不同而已。但是下面介紹的信號量的接口是用于線程的信號量&#xff0c;注意不要跟用于進程間通信…

linux下安裝erlang

1.安裝Erlang編譯依賴: yum -y install gcc glibc-devel make ncurses-devel openssl-devel xmlto perl wget 2.下載Erlang&#xff1a; wget http://www.erlang.org/download/otp_src_19.3.tar.gz 3.解壓并安裝 tar -xzvf otp_src_19.3.tar.gz cd otp_src_19.3 ./configure --…

Linux 線程同步的三種方法

http://blog.csdn.net/zsf8701/article/details/7844316 線程的最大特點是資源的共享性&#xff0c;但資源共享中的同步問題是多線程編程的難點。linux下提供了多種方式來處理線程同步&#xff0c;最常用的是互斥鎖、條件變量和信號量。 一、互斥鎖(mutex) 通過鎖機制實現線程…

Elixir特性

iex 退出&#xff1a;Ctrl-C 或Ctrl-G再輸入q 回車。 幫助文檔&#xff1a;h 查看輔函數列表 h IO 查看IO模塊幫助 h IO.puts 查看IO模塊中的puts函數的文檔 編譯和運行&#xff1a;創建一個hello.exs的文件。IO.puts "hello world"    //輸出hello world 使用el…

Elixir基礎

值類型 整數&#xff0c;包括十進制&#xff08;1234&#xff09;、十六進制&#xff08;0xcafe&#xff09;、八進制&#xff08;0o765&#xff09;和二進制&#xff08;0b1010&#xff09; 浮點數 原子&#xff0c;原子是常量&#xff0c;用于表現某些東西的名字&#xff0c;…

C++11新特性之八——函數對象function

http://www.cnblogs.com/yyxt/p/3987717.html 詳細請看《C Primer plus》(第六版中文版) http://www.cnblogs.com/lvpengms/archive/2011/02/21/1960078.html 備注&#xff1a; 函數對象&#xff1a; 盡管函數指針被廣泛用于實現函數回調&#xff0c;但C還提供了一個重要的實現…

分塊思想

今天學習了一個算法&#xff08;這個應該叫做算法吧&#xff1f;&#xff09;叫做分塊&#xff08;和莫隊&#xff0c;但是莫隊還沒有搞懂&#xff0c;搞懂再來寫吧&#xff09; 聽起來很高級&#xff0c;蒟蒻表示瑟瑟發抖。但是學完發現怎么那么像是一種變相的暴力呢。 分塊思…