裸機移植sqlite3
標簽: NUC970(ARM9) sqlite3 裸機sqlite3 移植sqlite3 STM32 SQLITE3
上一篇文章中提供了vfs支持,此處主要是sqlite3移植所需的線程,信號量支持,sqlite3源碼在官方下載,需要很大的內存支持,移植基本原理就是實現sqlite3所需的linux api接口即可,可以通過宏定義去掉一些不用的功能,減少API依賴。
ucos_iii_pthread.c
/*************************************************************************************************************
* 文件名 : ucos_iii_pthread.c
* 功能 : ucos_iii虛擬的pthread相關接口
* 作者 : [email protected]
* 創建時間 : 2020-09-29
* 最后修改時間 : 2020-09-29
* 詳細 : 用于實現sqlite3移植所需的信號量,線程操作相關接口
*************************************************************************************************************/
#include "system.h"
#include "ucos_iii_pthread.h"
#include <stdlib.h>
#include "errno-base.h"
#define MUTEXA_INIT_ID 0x12546f24 //用于標示互斥鎖是否初始化了
//內存申請接口
static void* (*pthread_malloc)(size_t size) = malloc; //默認的內存申請接口
static void (*pthread_free)(void *ptr) = free; //默認的內存釋放接口
/*************************************************************************************************************************
* 函數 : int pthread_mutexattr_init(pthread_mutexattr_t *mattr)
* 功能 : 初始化互斥鎖屬性
* 參數 : mattr:互斥鎖屬性對象
* 返回 : 0:成功;負數:返回錯誤碼
* 依賴 : ucos iii
* 作者 : [email protected]
* 時間 : 2020-09-29
* 最后修改時間 : 2020-09-29
* 說明 : pshared 屬性的 缺省值為 PTHREAD_PROCESS_PRIVATE。 該值表示可以在進程內使用經過初始化的 互斥鎖。
對于 互斥鎖屬性對象,必須首先通過調用 pthread_mutexattr_destroy(3C) 將其銷毀,才能重新初始化該對象
不會申請內存
*************************************************************************************************************************/
int pthread_mutexattr_init(pthread_mutexattr_t *mattr)
{
if(mattr == NULL) return -EINVAL;
mattr->InitId = MUTEXA_INIT_ID;
return 0;
}
/*************************************************************************************************************************
* 函數 : int pthread_mutexattr_settype(pthread_mutexattr_t *attr , int type)
* 功能 : 設置互斥鎖屬性類型
* 參數 : attr:互斥鎖指針;type:設置的屬性
* 返回 : 0:成功;負數:返回錯誤碼
* 依賴 : ucos iii
* 作者 : [email protected]
* 時間 : 2020-09-29
* 最后修改時間 : 2020-09-29
* 說明 : 此方法并沒有被實現
PTHREAD_MUTEX_NORMAL 描述: 此類型的 互斥鎖不會檢測 死鎖
PTHREAD_MUTEX_ERRORCHECK 描述: 此類型的 互斥鎖可提供錯誤檢查
PTHREAD_MUTEX_RECURSIVE 描述: 如果線程在不首先解除鎖定 互斥鎖的情況下嘗試重新鎖定該互斥鎖,則可成功鎖定該互斥鎖
PTHREAD_MUTEX_DEFAULT 描述: 如果嘗試以 遞歸方式鎖定此類型的 互斥鎖,則會產生不確定的行為
*************************************************************************************************************************/
int pthread_mutexattr_settype(pthread_mutexattr_t *attr , int type)
{
if(attr == NULL || attr->InitId != MUTEXA_INIT_ID) return -EINVAL;
uart_printf("pthread_mutexattr_settype(xxx, %d);\r\n", type);
return 0;
}
/*************************************************************************************************************************
* 函數 : int pthread_mutexattr_destroy(pthread_mutexattr_t *mattr)
* 功能 : 銷毀互斥鎖屬性對象
* 參數 : mattr:互斥鎖屬性對象
* 返回 : 0:成功;負數:返回錯誤碼
* 依賴 : ucos iii
* 作者 : [email protected]
* 時間 : 2020-09-29
* 最后修改時間 : 2020-09-29
* 說明 : 由于之前也沒有涉及到內存申請,此處只去掉初始化ID即可
*************************************************************************************************************************/
int pthread_mutexattr_destroy(pthread_mutexattr_t *mattr)
{
if(mattr == NULL) return -EINVAL;
mattr->InitId = 0;
return 0;
}
/*************************************************************************************************************************
* 函數 : int pthread_mutex_init(pthread_mutex_t *restrict mutex,const pthread_mutexattr_t *restrict attr)
* 功能 : 互斥鎖初始化
* 參數 : mutex:互斥鎖指針;attr:提前初始化的屬性信息
* 返回 : 0:成功;負數:返回錯誤碼
* 依賴 : ucos iii
* 作者 : [email protected]
* 時間 : 2020-09-29
* 最后修改時間 : 2020-09-29
* 說明 : 不會申請內存,調用ucos接口初始化互斥鎖
*************************************************************************************************************************/
int pthread_mutex_init(pthread_mutex_t * mutex, const pthread_mutexattr_t *attr)
{
OS_ERR err;
if(mutex == NULL || attr == NULL) return -EINVAL;
OSMutexCreate(&mutex->mutex, "Sqlite3", &err);
if(err == OS_ERR_NONE)
{
mutex->mattr = (pthread_mutexattr_t *)attr; //記錄互斥鎖屬性
mutex->InitId = MUTEXA_INIT_ID;
return 0; //初始化成功了
}
else
{
DEBUG("Sqlite3初始化互斥鎖失敗,錯誤:%d\r\n", err);
return -1;
}
}
/*************************************************************************************************************************
* 函數 : int pthread_mutex_destroy(pthread_mutex_t *mutex)
* 功能 : 銷毀一個互斥鎖
* 參數 : mutex:互斥鎖指針
* 返回 : 0:成功;負數:返回錯誤碼
* 依賴 : ucos iii
* 作者 : [email protected]
* 時間 : 2020-09-29
* 最后修改時間 : 2020-09-29
* 說明 : 調用ucos接口刪除互斥鎖
*************************************************************************************************************************/
int pthread_mutex_destroy(pthread_mutex_t *mutex)
{
OS_ERR err;
if(mutex == NULL || mutex->InitId != MUTEXA_INIT_ID) return -EINVAL;
OSMutexDel(&mutex->mutex, OS_OPT_DEL_ALWAYS, &err);
if(err == OS_ERR_NONE)
{
mutex->mattr = NULL; //記錄互斥鎖屬性清除
mutex->InitId = 0;
return 0; //初始化成功了
}
else
{
DEBUG("Sqlite3刪除互斥鎖失敗,錯誤:%d\r\n", err);
return -1;
}
}
/*************************************************************************************************************************
* 函數 : int pthread_mutex_lock(pthread_mutex_t *mutex)
* 功能 : 申請互斥鎖
* 參數 : mutex:互斥鎖指針
* 返回 : 0:成功;負數:返回錯誤碼
* 依賴 : ucos iii
* 作者 : [email protected]
* 時間 : 2020-09-29
* 最后修改時間 : 2020-09-29
* 說明 : 調用ucos接口申請互斥鎖
*************************************************************************************************************************/
int pthread_mutex_lock(pthread_mutex_t *mutex)
{
OS_ERR err;
CPU_TS ts;
if(mutex == NULL || mutex->InitId != MUTEXA_INIT_ID) return -EINVAL;
OSMutexPend(&mutex->mutex, 0, OS_OPT_PEND_BLOCKING, &ts, &err); //OS_OPT_PEND_BLOCKING阻塞等待
if(err == OS_ERR_NONE || err == OS_ERR_MUTEX_OWNER)
{
return 0;
}
else
{
DEBUG("Sqlite3申請互斥鎖失敗,錯誤:%d\r\n", err);
return -1;
}
}
/*************************************************************************************************************************
* 函數 : int pthread_mutex_trylock( pthread_mutex_t *mutex)
* 功能 : 非阻塞申請互斥鎖
* 參數 : mutex:互斥鎖指針
* 返回 : 0:成功;負數:返回錯誤碼
* 依賴 : ucos iii
* 作者 : [email protected]
* 時間 : 2020-09-29
* 最后修改時間 : 2020-09-29
* 說明 : 如果mutex參數所指定的互斥鎖已經被鎖定的話,調用pthread_mutex_trylock函數不會阻塞當前線程,而是立即返回一個值來描述互斥鎖的狀況
*************************************************************************************************************************/
int pthread_mutex_trylock( pthread_mutex_t *mutex)
{
OS_ERR err;
CPU_TS ts;
if(mutex == NULL || mutex->InitId != MUTEXA_INIT_ID) return -EINVAL;
OSMutexPend(&mutex->mutex, 0, OS_OPT_PEND_NON_BLOCKING, &ts, &err); //非阻塞,設置超時無意義
if(err == OS_ERR_NONE)
{
return 0; //信號量可用
}
else if(err == OS_ERR_PEND_WOULD_BLOCK) //當前信號量不可用
{
return -EBUSY;
}
else
{
DEBUG("Sqlite3申請互斥鎖失敗,錯誤:%d\r\n", err);
return -1;
}
}
/*************************************************************************************************************************
* 函數 : int pthread_mutex_unlock(pthread_mutex_t *mutex)
* 功能 : 互斥鎖解鎖
* 參數 : mutex:互斥鎖指針
* 返回 : 0:成功;負數:返回錯誤碼
* 依賴 : ucos iii
* 作者 : [email protected]
* 時間 : 2020-09-29
* 最后修改時間 : 2020-09-29
* 說明 :
*************************************************************************************************************************/
int pthread_mutex_unlock(pthread_mutex_t *mutex)
{
OS_ERR err;
if(mutex == NULL || mutex->InitId != MUTEXA_INIT_ID) return -EINVAL;
OSMutexPost(&mutex->mutex, OS_OPT_POST_NONE, &err); //釋放信號量
if(err == OS_ERR_NONE || err == OS_ERR_MUTEX_NESTING)
{
return 0; //成功
}
else
{
DEBUG("Sqlite3釋放互斥鎖失敗,錯誤:%d\r\n", err);
return -1;
}
}
#define PTHREAD_INIT_ID 0x55874187 //任務初始化id,標識任務是否被初始化了
//任務封裝
void pthread_task(void *p_arg)
{
ucosiii_pthread_type *pThread = (ucosiii_pthread_type*)p_arg;
if((pThread != NULL) && (pThread->InitId == PTHREAD_INIT_ID))
{
pThread->pTaskReturnValue = pThread->p_task(pThread->p_arg); //執行任務函數,記錄任務返回值
pThread->isExit = TRUE; //任務結束
}
}
/*************************************************************************************************************************
* 函數 : int pthread_create(pthread_t *tidp, const pthread_attr_t *attr, void *(*start_rtn)(void*), void *arg)
* 功能 : 線程創建
* 參數 : tidp:線程指針;attr:線程屬性;start_rtn:線程執行的函數;arg:線程執行函數的參數
* 返回 : 0:成功;負數:返回錯誤碼
* 依賴 : ucos iii
* 作者 : [email protected]
* 時間 : 2020-09-29
* 最后修改時間 : 2020-09-29
* 說明 :
*************************************************************************************************************************/
int pthread_create(pthread_t *tidp, const pthread_attr_t *attr, void *(*start_rtn)(void*), void *arg)
{
static u32 cnt; //每次調用自增一次,用于產生不同的名稱
ucosiii_pthread_type *pThread;
OS_ERR err;
if(start_rtn == NULL) return -EINVAL;
pThread = pthread_malloc(sizeof(ucosiii_pthread_type)); //申請內存
if(pThread == NULL)
{
DEBUG("Sqlite3創建線程失敗,內存不足!\r\n");
return -ENOMEM;
}
sprintf(pThread->p_name, "Sqlite_%d", cnt++); //產生隨機任務名稱
pThread->p_task = start_rtn; //任務函數
pThread->p_arg = arg; //任務參數
pThread->prio = SQLITE_PTHREAD_PRIO; //任務優先級
pThread->pThis = pThread; //記錄當前任務信息指針,并將任務指針當做任務參數傳遞到任務中
pThread->pTaskReturnValue = NULL; //任務返回值
pThread->isExit = FALSE; //任務未結束
pThread->InitId = 0; //任務初始化ID無效
OSTaskCreate(&pThread->TCB, //任務控制塊
(CPU_CHAR *)pThread->p_name, //任務的名字
pthread_task, //任務函數
pThread, //傳遞參數
pThread->prio, //任務的優先級
pThread->p_stk_base, //任務堆棧基地址
SQLITE_PTHREAD_STK_SIZE-64, //任務堆棧深度限位,用到這個位置,任務不能再繼續使用
SQLITE_PTHREAD_STK_SIZE, //任務堆棧大小
(OS_MSG_QTY)0, //禁止任務消息隊列
(OS_TICK)0, //默認時間片長度
(void *)0, //不需要補充用戶存儲區
(OS_OPT)OS_OPT_TASK_NONE, //沒有任何選項
&err //返回的錯誤碼
);
if(err == OS_ERR_NONE) //任務創建成功
{
*tidp = (u32)pThread; //返回任務的指針
pThread->InitId = PTHREAD_INIT_ID; //任務創建成功
DEBUG("SQLITE任務%s建立成功\r\n",pThread->p_name);
return 0;
}
else
{
pthread_free(pThread); //釋放掉申請的內存
*tidp = NULL;
DEBUG("SQLITE任務%s建立失敗,錯誤:%d\r\n",pThread->p_name, err);
return -1;
}
}
/*************************************************************************************************************************
* 函數 : int pthread_join(pthread_t thread, void **retval)
* 功能 : 等待一個線程的結束
* 參數 : tidp:線程指針;retval: 用戶定義的指針,用來存儲被等待線程的返回值
* 返回 : 0:成功;負數:返回錯誤碼
* 依賴 : ucos iii
* 作者 : [email protected]
* 時間 : 2020-09-29
* 最后修改時間 : 2020-09-29
* 說明 :
*************************************************************************************************************************/
int pthread_join(pthread_t thread, void **retval)
{
ucosiii_pthread_type *pThread = (ucosiii_pthread_type*)thread;
OS_ERR err;
if((pThread != NULL) && (pThread->InitId == PTHREAD_INIT_ID))
{
while(pThread->isExit == FALSE) //等待任務退出
{
Sleep(20);
}
//任務退出后就要銷毀任務了,可是這個返回值是個指針,如果是現成中申請的內存,需要用戶自己在返回數據使用完成后釋放掉
*retval = pThread->pTaskReturnValue; //任務的返回值
//開始銷毀任務,釋放內存了
OSTaskDel(&pThread->TCB, &err);
if(err == OS_ERR_NONE) //任務刪除成功
{
DEBUG("SQLITE任務%s刪除成功\r\n",pThread->p_name);
//釋放內存前,先清除掉一些重要數據,防止殘存在內存中
pThread->p_task = NULL; //任務函數
pThread->p_arg = 0; //任務參數
pThread->prio = 255; //任務優先級
pThread->pThis = NULL; //記錄當前任務信息指針,并將任務指針當做任務參數傳遞到任務中
pThread->pTaskReturnValue = NULL; //任務返回值
pThread->isExit = FALSE; //任務未結束
pThread->InitId = 0; //任務初始化ID無效
pthread_free(pThread); //釋放內存
return 0;
}
else
{
DEBUG("SQLITE任務%s刪除失敗,錯誤:%d\r\n",pThread->p_name, err);
return -1;
}
}
else return -1;
}
/*************************************************************************************************************************
* 函數 : pid_t getpid(void)
* 功能 : 獲取當前程序pid
* 參數 : 無
* 返回 : PID
* 依賴 :
* 作者 : [email protected]
* 時間 : 2020-09-29
* 最后修改時間 : 2020-09-29
* 說明 :
*************************************************************************************************************************/
pid_t getpid(void)
{
uart_printf("getpid()\r\n");
return 0;
}
/*************************************************************************************************************************
* 函數 : void sleep(u32 seconds)
* 功能 : 線程延時(單位秒)
* 參數 : 無
* 返回 : 無
* 依賴 :
* 作者 : [email protected]
* 時間 : 2020-09-29
* 最后修改時間 : 2020-09-29
* 說明 :
*************************************************************************************************************************/
void sleep(u32 seconds)
{
Sleep(seconds * 1000);
}
/*************************************************************************************************************************
* 函數 : void usleep(u64 usec)
* 功能 : 線程延時(單位us)
* 參數 : 無
* 返回 : 無
* 依賴 :
* 作者 : [email protected]
* 時間 : 2020-09-29
* 最后修改時間 : 2020-09-29
* 說明 :
*************************************************************************************************************************/
void usleep(u64 usec)
{
Sleep(usec / 1000);
}
/*************************************************************************************************************************
* 函數 : int gettimeofday(struct timeval *tp, void *ignore)
* 功能 : 獲取時間戳
* 參數 : tv:存放當前時間;ignore:忽略
* 返回 : 0:成功;負數:返回錯誤碼
* 依賴 :
* 作者 : [email protected]
* 時間 : 2020-09-29
* 最后修改時間 : 2020-09-29
* 說明 :
*************************************************************************************************************************/
int gettimeofday(struct timeval *tp, void *ignore)
{
uart_printf("gettimeofday(,)\r\n");
return 0;
}
//ucos_iii_pthread.h
/*************************************************************************************************************
* 文件名 : ucos_iii_pthread.h
* 功能 : ucos_iii虛擬的pthread相關接口
* 作者 : [email protected]
* 創建時間 : 2020-09-29
* 最后修改時間 : 2020-09-29
* 詳細 : 用于實現sqlite3移植所需的信號量,線程操作相關接口
*************************************************************************************************************/
#ifndef _UCOS_III_PTHREAD_H_
#define _UCOS_III_PTHREAD_H_
#ifdef __cplusplus
extern "C"
{
#endif
#include "system.h"
#include "main.h"
#include "ff_vfs.h"
//SQLITE相關配置宏定義
#define SQLITE_MAX_MMAP_SIZE 0 //不使用mmap
#define SQLITE_OMIT_WAL 1 //WAL機制
#define SQLITE_OMIT_LOAD_EXTENSION 1 //不使用動態加載庫
#define SQLITE_MALLOC(x) malloc(x)
#define SQLITE_FREE(x) free(x)
#define SQLITE_REALLOC(x,y) realloc((x),(y))
//互斥鎖屬性
typedef struct
{
u32 InitId;
}pthread_mutexattr_t;
//互斥鎖控制
typedef struct
{
OS_MUTEX mutex;
u32 InitId; //自己定義的一個,用于標示是否初始化了
pthread_mutexattr_t *mattr; //互斥鎖屬性
} pthread_mutex_t;
//互斥鎖類型設置
enum
{
PTHREAD_MUTEX_NORMAL = 0,
PTHREAD_MUTEX_RECURSIVE = 1,
PTHREAD_MUTEX_ERRORCHECK = 2,
PTHREAD_MUTEX_ERRORCHECK_NP = PTHREAD_MUTEX_ERRORCHECK,
PTHREAD_MUTEX_RECURSIVE_NP = PTHREAD_MUTEX_RECURSIVE,
PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_NORMAL
};
#define SQLITE_PTHREAD_PRIO SQLITE_TASK_PRIO //sqlite創建的線程優先級
#define SQLITE_PTHREAD_STK_SIZE (64*1024) //任務堆棧大小
//實際任務的信息
typedef struct
{
void *pThis; //指向當前的指針(將線程執行函數進行封裝,便于當線程結束后執行刪除線程操作,并獲取線程的返回值)
void *pTaskReturnValue; //任務返回值
bool isExit; //任務是否退出了
OS_TCB TCB; //線程控制塊
char p_name[24]; //線程名稱
void* (*p_task)(void*); //線程函數-兼容linux
void *p_arg; //線程參數
OS_PRIO prio; //線程優先級
CPU_STK p_stk_base[SQLITE_PTHREAD_STK_SIZE];//任務堆棧
u32 InitId; //任務初始化id
}ucosiii_pthread_type;
//任務句柄,此處實際上是個指向任務塊的指針
typedef unsigned int pthread_t; //存儲的是ucosiii_pthread_type的指針
typedef int pid_t;
//任務所需的信息-此處用不上,保留為一個整形數據就行
typedef unsigned int pthread_attr_t;
typedef int ssize_t;
#define timespec timeval
struct timezone {
int tz_minuteswest; /* minutes west of Greenwich */
int tz_dsttime; /* type of dst correction */
};
//互斥鎖
int pthread_mutexattr_init(pthread_mutexattr_t *mattr); //初始化互斥鎖屬性
int pthread_mutexattr_settype(pthread_mutexattr_t *attr , int type); //設置互斥鎖屬性類型
int pthread_mutexattr_destroy(pthread_mutexattr_t *mattr); //銷毀互斥鎖屬性對象
int pthread_mutex_init(pthread_mutex_t * mutex, const pthread_mutexattr_t *attr); //互斥鎖初始化
int pthread_mutex_destroy(pthread_mutex_t *mutex); //銷毀一個互斥鎖
int pthread_mutex_lock(pthread_mutex_t *mutex); //申請互斥鎖
int pthread_mutex_trylock( pthread_mutex_t *mutex); //非阻塞申請互斥鎖
int pthread_mutex_unlock(pthread_mutex_t *mutex); //互斥鎖解鎖
//線程相關
int pthread_create(pthread_t *tidp, const pthread_attr_t *attr, void *(*start_rtn)(void*), void *arg); //線程創建
int pthread_join(pthread_t thread, void **retval); //等待一個線程的結束
pid_t getpid(void); //獲取當前程序pid
void sleep(u32 seconds); //線程延時(單位秒)
void usleep(u64 usec); //線程延時(單位us)
int gettimeofday(struct timeval *tp, void *ignore); //獲取時間戳
#ifdef __cplusplus
}
#endif
#endif //_UCOS_III_PTHREAD_H_
請先初始化ucos以及文件系統,然后就可以初始化sqlite3,并查詢數據,測試代碼如下:
{
sqlite3 *ppDb;
int sta;
const char *pSQL = "SELECT *FROM \"tab\" WHERE id=2;";
char *zErrMsg = 0;
sqlite3_initialize();
sta = sqlite3_open("test.db", &ppDb);
if(sta == SQLITE_OK)
{
uart_printf("SQLITE打開數據庫成功\r\n");
//查詢數據
sta = sqlite3_exec( ppDb, pSQL, callback, NULL, &zErrMsg );
if( sta != SQLITE_OK)
{
uart_printf("%s: %s\r\n",pSQL, sqlite3_errmsg(ppDb));
if(zErrMsg)
{
uart_printf("ErrMsg = %s \r\n", zErrMsg);
sqlite3_free(zErrMsg);
}
}
sqlite3_close(ppDb);
}
else
{
uart_printf("SQLITE打開數據庫錯誤:%d\r\n", sta);
}
Sleep(10000000);
}
int callback(void* data, int ncols, char** values, char** headers)
{
int i;
int len =0;
int ll=0;
for(i=0; i < ncols; i++)
{
if(strlen(headers[i])>len)
len = strlen(headers[i]);
}
for(i=0; i < ncols; i++)
{
ll = len-strlen(headers[i]);
while(ll)
{
uart_printf(" ");
--ll;
}
uart_printf("%s: %s\r\n", headers[i], values[i]);
}
uart_printf("\r\n");
return 0;
}
測試結果
智能推薦
Sqlite3 基本操作
參考地址:https://www.runoob.com/sqlite/sqlite-tutorial.html 打開數據庫 數據庫若存在則打開數據庫,不存在則創建數據庫。 建表 創建表單techen,表單內容以及格式如下: 表單一共四條,分別是id,name,num,data,其中name是text類型,其余均為int類型。 主鍵是id和name 數據插入 插入或者替換表單中的一條數據,由于主鍵是...
Sqlite3性能測試
參考:http://blog.csdn.net/majiakun1/article/details/46607163,感謝作者分享。 Sqlite3最簡單的提升讀寫性能的方法有: 1. 關閉寫同步,也就是設置synchronous。Sqlite3是一個文件數據庫,所謂的設置寫同步就是設置每次寫完數據之后刷新IO緩存的頻率,如果寫同步設置為Full,那么每次寫都會刷新緩存,這樣保證數據總能寫到文件里...
freemarker + ItextRender 根據模板生成PDF文件
1. 制作模板 2. 獲取模板,并將所獲取的數據加載生成html文件 2. 生成PDF文件 其中由兩個地方需要注意,都是關于獲取文件路徑的問題,由于項目部署的時候是打包成jar包形式,所以在開發過程中時直接安照傳統的獲取方法沒有一點文件,但是當打包后部署,總是出錯。于是參考網上文章,先將文件讀出來到項目的臨時目錄下,然后再按正常方式加載該臨時文件; 還有一個問題至今沒有解決,就是關于生成PDF文件...
猜你喜歡
電腦空間不夠了?教你一個小秒招快速清理 Docker 占用的磁盤空間!
Docker 很占用空間,每當我們運行容器、拉取鏡像、部署應用、構建自己的鏡像時,我們的磁盤空間會被大量占用。 如果你也被這個問題所困擾,咱們就一起看一下 Docker 是如何使用磁盤空間的,以及如何回收。 docker 占用的空間可以通過下面的命令查看: TYPE 列出了docker 使用磁盤的 4 種類型: Images:所有鏡像占用的空間,包括拉取下來的鏡像,和本地構建的。 Con...
requests實現全自動PPT模板
http://www.1ppt.com/moban/ 可以免費的下載PPT模板,當然如果要人工一個個下,還是挺麻煩的,我們可以利用requests輕松下載 訪問這個主頁,我們可以看到下面的樣式 點每一個PPT模板的圖片,我們可以進入到詳細的信息頁面,翻到下面,我們可以看到對應的下載地址 點擊這個下載的按鈕,我們便可以下載對應的PPT壓縮包 那我們就開始做吧 首先,查看網頁的源代碼,我們可以看到每一...
Linux C系統編程-線程互斥鎖(四)
互斥鎖 互斥鎖也是屬于線程之間處理同步互斥方式,有上鎖/解鎖兩種狀態。 互斥鎖函數接口 1)初始化互斥鎖 pthread_mutex_init() man 3 pthread_mutex_init (找不到的情況下首先 sudo apt-get install glibc-doc sudo apt-get install manpages-posix-dev) 動態初始化 int pthread_...
統計學習方法 - 樸素貝葉斯
引入問題:一機器在良好狀態生產合格產品幾率是 90%,在故障狀態生產合格產品幾率是 30%,機器良好的概率是 75%。若一日第一件產品是合格品,那么此日機器良好的概率是多少。 貝葉斯模型 生成模型與判別模型 判別模型,即要判斷這個東西到底是哪一類,也就是要求y,那就用給定的x去預測。 生成模型,是要生成一個模型,那就是誰根據什么生成了模型,誰就是類別y,根據的內容就是x 以上述例子,判斷一個生產出...