Linux下c開發 之 線程通信與pthread_cond_wait()的使用

pthread_cond_wait()

/************pthread_cond_wait()的使用方法**********/
pthread_mutex_lock(&qlock); ? ?
pthread_cond_wait(&qready, &qlock);
pthread_mutex_unlock(&qlock);
/*****************************************************/
The mutex passed to pthread_cond_wait protects the condition.The caller?passes it locked to the function, which then atomically places them?calling thread on the list of threads waiting for the condition and?unlocks the mutex. This closes the window between the time that the?condition is checked and the time that the thread goes to sleep waiting?for the condition to change, so that the thread doesn't miss a change?in the condition. When pthread_cond_wait returns, the mutex is again?locked.
上面是APUE的原話,就是說pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)函數傳入的參數mutex用于保護條件,因為我們在調用pthread_cond_wait時,如果條件不成立我們就進入阻塞,但是進入阻塞這個期間,如果條件變量改變了的話,那我們就漏掉了這個條件。因為這個線程還沒有放到等待隊列上,所以調用pthread_cond_wait前要先鎖互斥量,即調用pthread_mutex_lock(),pthread_cond_wait在把線程放進阻塞隊列后,自動對mutex進行解鎖,使得其它線程可以獲得加鎖的權利。這樣其它線程才能對臨界資源進行訪問并在適當的時候喚醒這個阻塞的進程。當pthread_cond_wait返回的時候又自動給mutex加鎖
實際上邊代碼的加解鎖過程如下:
/************pthread_cond_wait()的使用方法**********/
pthread_mutex_lock(&qlock); ? ?/*lock*/
pthread_cond_wait(&qready, &qlock); /*block-->unlock-->wait() return-->lock*/
pthread_mutex_unlock(&qlock); /*unlock*/
/*****************************************************/

#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
#include <stdlib.h>
#include <time.h>
#include <pthread.h>

void* testThreadPool(int *t);
pthread_mutex_t clifd_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t clifd_cond = PTHREAD_COND_INITIALIZER;
int a = 0;

int main() {

int sock_fd, conn_fd;
int optval;

socklen_t cli_len;
struct sockaddr_in cli_addr, serv_addr;


sock_fd = socket(AF_INET, SOCK_STREAM, 0);
if (sock_fd < 0) {
?? printf("socket\n");
}

optval = 1;
if (setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, (void *) &optval,
??? sizeof(int)) < 0) {
?? printf("setsockopt\n");
}

memset(&serv_addr, 0, sizeof(struct sockaddr_in));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(4507);
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);

if (bind(sock_fd, (struct sockaddr *) &serv_addr,
??? sizeof(struct sockaddr_in)) < 0) {
?? printf("bind\n");
}

if (listen(sock_fd, 100) < 0) {
?? printf("listen\n");
}

cli_len = sizeof(struct sockaddr_in);
int t;
pthread_t * mythread;
mythread = (pthread_t*) malloc(100 * sizeof(pthread_t));
for (t = 0; t < 5; t++) {
?? int *i=(int*)malloc(sizeof(int));
?? *i=t;
?? if (pthread_create(&mythread[t], NULL, (void*)testThreadPool, (void*)i) != 0) {
??? printf("pthread_create");
?? }
}

while (1) {
?? conn_fd = accept(sock_fd, (struct sockaddr *) &cli_addr, &cli_len);
?? if (conn_fd < 0) {
??? printf("accept\n");
?? }
?? printf("accept a new client, ip:%s\n", inet_ntoa(cli_addr.sin_addr));

?? pthread_mutex_lock(&clifd_mutex);
?? a=conn_fd;
?? pthread_cond_signal(&clifd_cond);
?? pthread_mutex_unlock(&clifd_mutex);
}
return 0;
}

void* testThreadPool(int *t) {

printf("t is %d\n", *t);
for (;;) {
?? pthread_mutex_lock(&clifd_mutex);
?? pthread_cond_wait(&clifd_cond, &clifd_mutex);
?? printf("a is %d\n", a);
?? printf("t is %d\n", *t);
?? pthread_mutex_unlock(&clifd_mutex);
?? sleep(100);
}
return (void*) 0;
}

了解 pthread_cond_wait() 的作用非常重要 -- 它是 POSIX 線程信號發送系統的核心,也是最難以理解的部分。

首先,讓我們考慮以下情況:線程為查看已鏈接列表而鎖定了互斥對象,然而該列表恰巧是空的。這一特定線程什么也干不了 -- 其設計意圖是從列表中除去節點,但是現在卻沒有節點。因此,它只能:

鎖定互斥對象時,線程將調用 pthread_cond_wait(&mycond,&mymutex)。pthread_cond_wait() 調用相當復雜,因此我們每次只執行它的一個操作。

pthread_cond_wait() 所做的第一件事就是同時對互斥對象解鎖(于是其它線程可以修改已鏈接列表),并等待條件 mycond 發生(這樣當 pthread_cond_wait() 接收到另一個線程的“信號”時,它將蘇醒)。現在互斥對象已被解鎖,其它線程可以訪問和修改已鏈接列表,可能還會添加項。 【要求解鎖并阻塞是一個原子操作

此時,pthread_cond_wait() 調用還未返回。對互斥對象解鎖會立即發生,但等待條件 mycond 通常是一個阻塞操作,這意味著線程將睡眠,在它蘇醒之前不會消耗 CPU 周期。這正是我們期待發生的情況。線程將一直睡眠,直到特定條件發生,在這期間不會發生任何浪費 CPU 時間的繁忙查詢。從線程的角度來看,它只是在等待 pthread_cond_wait() 調用返回。

現在繼續說明,假設另一個線程(稱作“2 號線程”)鎖定了 mymutex 并對已鏈接列表添加了一項。在對互斥對象解鎖之后,2 號線程會立即調用函數 pthread_cond_broadcast(&mycond)。此操作之后,2 號線程將使所有等待 mycond 條件變量的線程立即蘇醒。這意味著第一個線程(仍處于 pthread_cond_wait() 調用中)現在將蘇醒

現在,看一下第一個線程發生了什么。您可能會認為在 2 號線程調用 pthread_cond_broadcast(&mymutex) 之后,1 號線程的 pthread_cond_wait() 會立即返回。不是那樣!實際上,pthread_cond_wait() 將執行最后一個操作:重新鎖定 mymutex。一旦 pthread_cond_wait() 鎖定了互斥對象,那么它將返回并允許 1 號線程繼續執行。那時,它可以馬上檢查列表,查看它所感興趣的更改。

停止并回顧!
那個過程非常復雜,因此讓我們先來回顧一下。第一個線程首先調用:
pthread_mutex_lock(&mymutex);
然后,它檢查了列表。沒有找到感興趣的東西,于是它調用:
pthread_cond_wait(&mycond, &mymutex);
 
然后,pthread_cond_wait() 調用在返回前執行許多操作:
?
pthread_mutex_unlock(&mymutex);
?
它對 mymutex 解鎖,然后進入睡眠狀態,等待 mycond 以接收 POSIX 線程“信號”。一旦接收到“信號”(加引號是因為我們并不是在討論傳統的 UNIX 信號,而是來自 pthread_cond_signal() 或 pthread_cond_broadcast() 調用的信號),它就會蘇醒。但 pthread_cond_wait() 沒有立即返回 -- 它還要做一件事:重新鎖定 mutex:
pthread_mutex_lock(&mymutex);
?
pthread_cond_wait() 知道我們在查找 mymutex “背后”的變化,因此它繼續操作,為我們鎖定互斥對象,然后才返回。

1.Linux“線程”

?????進程與線程之間是有區別的,不過Linux內核只提供了輕量進程的支持,未實現線程模型。Linux是一種“多進程單線程”的操作系統。Linux本身只有進程的概念,而其所謂的“線程”本質上在內核里仍然是進程。

?????大家知道,進程是資源分配的單位,同一進程中的多個線程共享該進程的資源(如作為共享內存的全局變量)。Linux中所謂的“線程”只是在被創建時clone了父進程的資源,因此clone出來的進程表現為“線程”,這一點一定要弄清楚。因此,Linux“線程”這個概念只有在打冒號的情況下才是最準確的。

?????目前Linux中最流行的線程機制為LinuxThreads,所采用的就是線程-進程“一對一”模型,調度交給核心,而在用戶級實現一個包括信號處理在內的線程管理機制。LinuxThreads由Xavier Leroy (Xavier.Leroy@inria.fr)負責開發完成,并已綁定在GLIBC中發行,它實現了一種BiCapitalized面向Linux的Posix 1003.1c “pthread”標準接口。Linuxthread可以支持Intel、Alpha、MIPS等平臺上的多處理器系統。

  按照POSIX 1003.1c 標準編寫的程序與Linuxthread 庫相鏈接即可支持Linux平臺上的多線程,在程序中需包含頭文件pthread. h,在編譯鏈接時使用命令:

gcc -D -REENTRANT -lpthread xxx. c

  其中-REENTRANT宏使得相關庫函數(如stdio.h、errno.h中函數) 是可重入的、線程安全的(thread-safe),-lpthread則意味著鏈接庫目錄下的libpthread.a或libpthread.so文件。使用Linuxthread庫需要2.0以上版本的Linux內核及相應版本的C庫(libc 5.2.18、libc 5.4.12、libc 6)。

?????2.“線程”控制

  線程創建

  進程被創建時,系統會為其創建一個主線程,而要在進程中創建新的線程,則可以調用pthread_create:

pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *
(start_routine)(void*), void *arg);

  start_routine為新線程的入口函數,arg為傳遞給start_routine的參數。

  每個線程都有自己的線程ID,以便在進程內區分。線程ID在pthread_create調用時回返給創建線程的調用者;一個線程也可以在創建后使用pthread_self()調用獲取自己的線程ID:

pthread_self (void) ;

  線程退出

  線程的退出方式有三:

  (1)執行完成后隱式退出;

  (2)由線程本身顯示調用pthread_exit 函數退出;

pthread_exit (void * retval) ;

  (3)被其他線程用pthread_cance函數終止:

pthread_cance (pthread_t thread) ;

  在某線程中調用此函數,可以終止由參數thread 指定的線程。

  如果一個線程要等待另一個線程的終止,可以使用pthread_join函數,該函數的作用是調用pthread_join的線程將被掛起直到線程ID為參數thread的線程終止:

pthread_join (pthread_t thread, void** threadreturn);

3.線程通信

  線程互斥

  互斥意味著“排它”,即兩個線程不能同時進入被互斥保護的代碼。Linux下可以通過pthread_mutex_t 定義互斥體機制完成多線程的互斥操作,該機制的作用是對某個需要互斥的部分,在進入時先得到互斥體,如果沒有得到互斥體,表明互斥部分被其它線程擁有,此時欲獲取互斥體的線程阻塞,直到擁有該互斥體的線程完成互斥部分的操作為止。

  下面的代碼實現了對共享全局變量x 用互斥體mutex 進行保護的目的:

int x; // 進程中的全局變量
pthread_mutex_t mutex;
pthread_mutex_init(&mutex, NULL); //按缺省的屬性初始化互斥體變量mutex
pthread_mutex_lock(&mutex); // 給互斥體變量加鎖
… //對變量x 的操作
phtread_mutex_unlock(&mutex); // 給互斥體變量解除鎖

  線程同步

  同步就是線程等待某個事件的發生。只有當等待的事件發生線程才繼續執行,否則線程掛起并放棄處理器。當多個線程協作時,相互作用的任務必須在一定的條件下同步。

  Linux下的C語言編程有多種線程同步機制,最典型的是條件變量(condition variable)。pthread_cond_init用來創建一個條件變量,其函數原型為:

pthread_cond_init (pthread_cond_t *cond, const pthread_condattr_t *attr);

  pthread_cond_wait和pthread_cond_timedwait用來等待條件變量被設置,值得注意的是這兩個等待調用需要一個已經上鎖的互斥體mutex,這是為了防止在真正進入等待狀態之前別的線程有可能設置該條件變量而產生競爭。pthread_cond_wait的函數原型為:

pthread_cond_wait (pthread_cond_t *cond, pthread_mutex_t *mutex);

  pthread_cond_broadcast用于設置條件變量,即使得事件發生,這樣等待該事件的線程將不再阻塞

pthread_cond_broadcast (pthread_cond_t *cond) ;

  pthread_cond_signal則用于解除某一個等待線程的阻塞狀態:

pthread_cond_signal (pthread_cond_t *cond) ;

  pthread_cond_destroy 則用于釋放一個條件變量的資源。

  在頭文件semaphore.h 中定義的信號量則完成了互斥體和條件變量的封裝,按照多線程程序設計中訪問控制機制,控制對資源的同步訪問,提供程序設計人員更方便的調用接口。

sem_init(sem_t *sem, int pshared, unsigned int val);

  這個函數初始化一個信號量sem 的值為val,參數pshared 是共享屬性控制,表明是否在進程間共享。

sem_wait(sem_t *sem);

  調用該函數時,若sem為無狀態,調用線程阻塞,等待信號量sem值增加(post )成為有信號狀態;若sem為有狀態,調用線程順序執行,但信號量的值減一。

sem_post(sem_t *sem);

  調用該函數,信號量sem的值增加,可以從無信號狀態變為有信號狀態。

?????

?

4.實例

  下面我們還是以名的生產者/消費者問題為例來闡述Linux線程的控制和通信。一組生產者線程與一組消費者線程通過緩沖區發生聯系。生產者線程將生產的產品送入緩沖區,消費者線程則從中取出產品。緩沖區有N 個,是一個環形的緩沖池。

#include <stdio.h>
#include <pthread.h>
#define BUFFER_SIZE 16 // 緩沖區數量
struct prodcons
{
// 緩沖區相關數據結構
int buffer[BUFFER_SIZE]; /* 實際數據存放的數組*/
pthread_mutex_t lock; /* 互斥體lock 用于對緩沖區的互斥操作 */
int readpos, writepos; /* 讀寫指針*/
pthread_cond_t notempty; /* 緩沖區非空的條件變量 */
pthread_cond_t notfull; /* 緩沖區未滿的條件變量 */
};
/* 初始化緩沖區結構 */
void init(struct prodcons *b)
{
pthread_mutex_init(&b->lock, NULL);
pthread_cond_init(&b->notempty, NULL);
pthread_cond_init(&b->notfull, NULL);
b->readpos = 0;
b->writepos = 0;
}
/* 將產品放入緩沖區,這里是存入一個整數*/
void put(struct prodcons *b, int data)
{
pthread_mutex_lock(&b->lock);
/* 等待緩沖區未滿*/
if ((b->writepos + 1) % BUFFER_SIZE == b->readpos)
{
pthread_cond_wait(&b->notfull, &b->lock);
}
/* 寫數據,并移動指針 */
b->buffer[b->writepos] = data;
b->writepos++;
if (b->writepos > = BUFFER_SIZE)
b->writepos = 0;
/* 設置緩沖區非空的條件變量*/
pthread_cond_signal(&b->notempty);
pthread_mutex_unlock(&b->lock);
}
/* 從緩沖區中取出整數*/
int get(struct prodcons *b)
{
int data;
pthread_mutex_lock(&b->lock);
/* 等待緩沖區非空*/
if (b->writepos == b->readpos)
{
pthread_cond_wait(&b->notempty, &b->lock);
}
/* 讀數據,移動讀指針*/
data = b->buffer[b->readpos];
b->readpos++;
if (b->readpos > = BUFFER_SIZE)
b->readpos = 0;
/* 設置緩沖區未滿的條件變量*/
pthread_cond_signal(&b->notfull);
pthread_mutex_unlock(&b->lock);
return data;
}

/* 測試:生產者線程將1 到10000 的整數送入緩沖區,消費者線
程從緩沖區中獲取整數,兩者都打印信息*/
#define OVER ( - 1)
struct prodcons buffer;
void *producer(void *data)
{
int n;
for (n = 0; n < 10000; n++)
{
printf("%d --->\n", n);
put(&buffer, n);
} put(&buffer, OVER);
return NULL;
}

void *consumer(void *data)
{
int d;
while (1)
{
d = get(&buffer);
if (d == OVER)
break;
printf("--->%d \n", d);
}
return NULL;
}

int main(void)
{
pthread_t th_a, th_b;
void *retval;
init(&buffer);
/* 創建生產者和消費者線程*/
pthread_create(&th_a, NULL, producer, 0);
pthread_create(&th_b, NULL, consumer, 0);
/* 等待兩個線程結束*/
pthread_join(th_a, &retval);
pthread_join(th_b, &retval);
return 0;
}
5.WIN32、VxWorks、Linux線程類比

  目前為止,筆者已經創作了《基于嵌入式操作系統VxWorks的多任務并發程序設計》(《軟件報》2006年5~12期連載)、《深入淺出Win32多線程程序設計》(天極網技術專題)系列,我們來找出這兩個系列文章與本文的共通點。

   看待技術問題要瞄準其本質,不管是Linux、VxWorks還是WIN32,其涉及到多線程的部分都是那些內容,無非就是線程控制和線程通信,它們的許多函數只是名稱不同,其實質含義是等價的,下面我們來列個三大操作系統共同點詳細表單:

事項WIN32VxWorksLinux
線程創建CreateThreadtaskSpawnpthread_create
線程終止執行完成后退出;線程自身調用ExitThread函數即終止自己;被其他線程調用函數TerminateThread函數執行完成后退出;由線程本身調用exit退出;被其他線程調用函數taskDelete終止執行完成后退出;由線程本身調用pthread_exit 退出;被其他線程調用函數pthread_cance終止
獲取線程IDGetCurrentThreadIdtaskIdSelfpthread_self
創建互斥CreateMutexsemMCreatepthread_mutex_init
獲取互斥WaitForSingleObject、WaitForMultipleObjectssemTakepthread_mutex_lock
釋放互斥ReleaseMutexsemGivephtread_mutex_unlock
創建信號量CreateSemaphoresemBCreate、semCCreatesem_init
等待信號量WaitForSingleObjectsemTakesem_wait
釋放信號量ReleaseSemaphoresemGivesem_post

   6.小結

  本章講述了Linux下多線程的控制及線程間通信編程方法,給出了一個生產者/消費者的實例,并將Linux的多線程與WIN32、VxWorks多線程進行了類比,總結了一般規律。鑒于多線程編程已成為開發并發應用程序的主流方法,學好本章的意義也便不言自明。

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

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

相關文章

ROS與navigation教程——ACML參數配置

<launch> <!--//后為wiki官網的參數說明 &#xff08;&#xff09;中為粗讀算法參數說明及理解 面臨的問題常用地圖有2種&#xff1a;1.基于特征&#xff0c;僅指明在指定位置&#xff08;地圖中包含的對象的位置&#xff09;的環境的形狀。特征表示使得調節對象的位置…

【設計模式】單例模式 Singleton Pattern

通常我們在寫程序的時候會碰到一個類只允許在整個系統中只存在一個實例&#xff08;Instance&#xff09; 的情況&#xff0c; 比如說我們想做一計數器&#xff0c;統計某些接口調用的次數&#xff0c;通常我們的數據庫連接也是只期望有一個實例。Windows系統的系統任務管理器…

修改輸入框placeholder的默認樣式

一般網頁中都用到input的placeholder屬性&#xff0c;想讓這個默認樣式和網頁保持一致&#xff0c;就需要重新設定樣式&#xff0c;百度百度&#xff1a; :-moz-placeholder { / color: #000; opacity:1; }支持/* Mozilla Firefox 4 to 18 * ::-moz-placeholder { color: #000;…

進程及線程通信總結

上文我們介紹了如何建立一個簡單的多線程程序&#xff0c;多線程之間不可避免的需要進行通信 。相比于進程間通信來說&#xff0c;線程間通信無疑是相對比較簡單的。 首先我們來看看最簡單的方法&#xff0c;那就是使用全局變量&#xff08;靜態變量也可以&#xff09;來進行通…

ROS multi-master——multimaster_fkie配置

多主站ROS配置和mutimaster_fkie ROS版本&#xff1a;kinetic 操作系統&#xff1a;Ubuntu 16.04。 multimaster_fkie&#xff1a;github 1網絡配置 1.1路由器 設置無線路由器并連接兩臺計算機/機器人。為這兩臺計算機設置靜態IP地址。相互測試ping命令和ssh。 1.2主機 …

Docker入門

1. Docker簡介: docker是一個基于LXC的高級容器引擎。簡單地說&#xff0c;docker是一個輕量級的虛擬解決方案&#xff0c;或者說它是一個超輕量級的虛擬機&#xff08;容器&#xff09;。 Docker是一個開源的引擎&#xff0c;可以輕松的為任何應用創建一個輕量級的、可移植的、…

樂器庫的混合

每臺微機一個聲卡&#xff0c;也就是一片D/A&#xff0c;驅動按波特率、采樣位數、采樣通道傳輸給D/A&#xff0c;輸出模擬音頻。播放時僅一種與硬件支持格式對應&#xff0c;其他需驅動&#xff08;有損&#xff09;變換到硬件支持格式。每個應用都可單獨播放聲音&#xff0c;…

kafka認知--(1)

文檔參考&#xff1a;http://kafka.apache.org/documentation.html 下載代碼&#xff1a; tar -xzf kafka_2.11-0.11.0.0.tgz cd kafka_2.11-0.11.0.0 啟動 bin/zookeeper-server-start.sh config/zookeeper.properties 創建topic&#xff08;主題為test&#xff0c;只有一個分…

帶頭尾指針的list的C實現

一、緣起 很早寫了一個帶頭尾指針的list&#xff0c;該list支持從尾部插入元素&#xff0c;在任意位置刪除元素&#xff0c;最近用這個list時發現一個bug&#xff0c;修正了&#xff0c;并加了幾個接口函數。貼出來&#xff0c;希望對C的初學者有用。 二、基本說明 2.1、數據結…

Gmapping——從原理到實踐

概述 在SLAM中&#xff0c;機器人位姿和地圖都是狀態變量&#xff0c;我們需要同時對這兩個狀態變量進行估計&#xff0c;即機器人獲得一張環境地圖的同時確定自己相對于該地圖的位置。我們用x表示機器人狀態&#xff0c;m表示環境地圖&#xff0c;z表示傳感器觀測情況&#xf…

關于git分支

1.關于git分支 git的“分支”乍一聽是一個特別容易讓人產生錯覺的概念&#xff0c;以為它和樹枝一樣是分叉的枝節&#xff0c;其實Git中的分支本質上是個指向commit對象的指針,每次commit&#xff0c;git都把它們串成一條時間線&#xff0c;這條時間線就是一個分支。 2.直接切換…

【機器學習經典算法源碼分析系列】-- 邏輯回歸

1.邏輯回歸&#xff08;Logistic Regression&#xff09;又常被成為“邏輯斯蒂回歸”&#xff0c;實質上是一個二元分類問題。 邏輯回歸代價函數&#xff1a; 代價函數導數&#xff1a; Matlab實現&#xff1a; 采用matlab中自帶的無約束最小化函數fminunc來代替梯度下降法&…

求特殊自然數

總時間限制: 1000ms 內存限制: 65536kB 描述一個十進制自然數,它的七進制與九進制表示都是三位數&#xff0c;且七進制與九進制的三位數碼表示順序正好相反。編程求此自然數,并輸出顯示。 輸入無。輸出三行&#xff1a;第一行是此自然數的十進制表示&#xff1b;第一行是此自然…

ROS——不同版本間ROS進行通信

在相同版本間的ROS進行通信不在贅述了&#xff0c;修改/etc/hosts文件即可。 最近項目遇到在Ubuntu16.04 與Ubuntu18.04兩個系統間進行ROS通信&#xff0c;ROS版本分別為Kinetic和Melodic。配置網絡后&#xff0c;兩邊都能夠ping通&#xff0c;但是在獲取ros數據是&#xff0c…

大數據開發實戰:數據流圖及相關數據技術

1、大數據流程圖 2、大數據各個環節主要技術 2.1、數據處理主要技術 Sqoop&#xff1a;&#xff08;發音&#xff1a;skup&#xff09;作為一款開源的離線數據傳輸工具&#xff0c;主要用于Hadoop(Hive) 與傳統數據庫&#xff08;MySql,PostgreSQL&#xff09;間的數據傳遞。它…

oracle 中時間類型 date 與 long 互轉

我們在保存時間到數據庫時&#xff0c;有時候會保存long型的數據&#xff0c;固定長度是13位&#xff0c;是用當前時間減去1970-01-01&#xff0c;再換算成毫秒得到的結果。 但是要考慮到時區問題中國的時區時8區所以時間要加上8小時 oracle中的實現方式&#xff1a; ---------…

Linux對包管理闡述

Centos/Redhat/Fedora的軟件包&#xff0c;都是rpm后綴的文件。包管理器rpm(Redhat packages manager) linux的哲學思想是簡單命令解決復雜任務&#xff0c;因此每個軟件的功能較單一&#xff0c;所以各種包之間有著復雜的依賴關系&#xff0c;為了解決這種可以使用前端工具&am…

跨時鐘域電路設計——亞穩態及雙鎖存器

一、同步電路 定義&#xff1a;電路中所有受時鐘控制的單元&#xff0c;全部由一個統一的時鐘控制。 優點&#xff1a;在同步設計中&#xff0c;EDA工具可以保證電路系統的時序收斂&#xff0c;避免電路設計中的競爭冒險。 缺點&#xff1a;時鐘樹綜合需要加入大量延遲單元&…

linux setsockopt詳解

1.closesocket&#xff08;一般不會立即關閉而經歷TIME_WAIT的過程&#xff09;后想繼續重用該socket&#xff1a; BOOL bReuseaddrTRUE; setsockopt(s,SOL_SOCKET ,SO_REUSEADDR,(const char*)&bReuseaddr,sizeof(BOOL)); 2. 如果要已經處于連接狀態的soket在調用closes…

[TOOLS] 移動端調試進行時 - whistle

1、本地安裝、啟動whistle 安裝實操請查看官方文檔不贅述 復制代碼 2、手機設置代理 實操請查看官方文檔 !!!注意&#xff1a;代理ip填寫whistle右上角online選項中的ip 復制代碼 3、whistle上設置對應rules、weinre whistle設置代理(!!!注意支持tunnel協議)&#xff1a; rules…