Rsync
非常適合在兩台機器之間快速同步大型、復雜的目錄,例如論壇的附件目錄。再配合
ssh
,則安全性也有保證,且可以利用
ssh
public
key
和
cron
來進行自動定時同步。
說明:兩台機器分別為
localhost
和
remotehost
;用戶分別為
localuser
和
remoteuser。
環境:FreeBSD
4.9
和
FreeBSD
6.1
代碼如下
設置
ssh
public
key
認證
$ssh-keygen
-t
dsa
-b
2048
生成所需的密鑰
$scp
/home/localuser/.ssh/id_dsa.pub
remoteuser@remotehost:/home/remoteuser/.ssh/localuser_id_dsa.pub
將公鑰拷貝至
remotehost
$ssh
remoteuser@remotehost
登錄到?端
代碼如下
$cd
.ssh/
;
cat
localuser_id_dsa.pub
>>
authorized_keys
至此,設置
ssh
認證完畢。
設置
rsync
確認兩端機器都安裝
rsync
,
freeBSD
有
ports
,安裝非常方便。
寫個腳本名為
backup.sh
,內容如下:
代碼如下
#!/bin/sh
RSYNC=/usr/local/bin/rsync
SSH=/usr/bin/ssh
KEY=/home/localuser/.ssh
/id_rsa
RUSER=remoteuser
RHOST=remotehost
RPATH=/remote/dir
LPATH=/this/dir
$RSYNC
-az—delte
-e
“$SSH
-i
$KEY”
$RUSER@$RHOST:$RPATH
$LPATH
-a
選項相當於選項
-rlptgoD
。簡單來講,此選項可遞歸並將幾乎所有的東西同步過去,非常有用。注意的是,
-a
默認不會保存
hardlinks
,不過可以單獨用
-H
選項來實現。
-z
選項在傳輸中壓縮文件,這無疑加快同步速度。
-delete
選項會刪除接受方一些不應存在的文件,此文件在發送方已經被刪除,這將保持目錄完全同步。
讓
cron
每天凌晨1點來跑這個腳本
代碼如下
$crontab
-e
0
1
*
*
*
/home/localuser/bin/backup.sh
友情提示
rsync是沒有自動啟動同步功能了,如果我們要定時去備份一個網站數據我們就需要用到定時功能了,上面的例子來使用到了linux中$crontab命令來定時執行備份數據腳本了哦。
Ⅱ linux非同步IO怎麼理解
就是來IO不阻塞即使沒有數自據可讀,或者空間可寫時。非同步IO都返回,不管如何情況。簡單點的意思就是進程不會阻塞在你讀寫調用非同步IO系統調用的時候。所以你的執行流可以去做其它的事情,當你確實要確認數據讀寫成功的時候,你在用aio_return這個函數去判斷讀寫成功了嗎。如果你想耗費cpu那你就一值調用aio_return輪詢結果。如果想睡眠等待讀寫完成,那麼你調用aio_suspend這個函數,你就會睡眠,當讀寫完成時,內核會發信號給你,這時,就會執行信號處理函數,並喚醒此進程。要充分理解非同步IO,最好把信號和非同步通知一起搞懂。如果會寫驅動的話,最好自己去實現IO的這些功能,比如阻塞IO,非阻塞IO,輪詢,非同步通知,非同步IO等等,其中又涉及到並發和競爭的問題。
Ⅲ Linux中同步信號和非同步信號分別怎麼解釋
Linux非同步信號
1.int pthread_kill(pthread_t threadid, intsigno);
向特定的線程發送信號signo
2.int pthread_sigmask(int how, const sigset_t*newmask, sigset_t *oldmask);
設置線程的信號屏蔽碼
3.int sigwait(const sigset_t *set, int *sig);
阻塞線程,等待set中指定的信號之一到達,並將到達的信號存入*sig。
4.代碼
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <signal.h>
//#define SIGUSRR 40;
int SIGUSRR = 40;
void* threadOne(void *arg)
{
sigset_tsigset;
intsigno;
sigemptyset(&sigset);
sigaddset(&sigset,SIGUSRR);
pthread_sigmask(SIG_BLOCK,&sigset, NULL);
while(1)
{
sigwait(&sigset,&signo);
printf("getthread cond sig!\n");
}
}
int main(int argc, char **argv)
{
if(argc != 1)
{
printf("Usage:\n");
printf("threadcond\n");
return1;
}
pthread_tthreadId;
if(pthread_create(&threadId,NULL, threadOne, NULL) != 0)
{
printf("threadcreate error! \n");
return1;
}
//structsigaction act;
//act.sa_handler=SIG_IGN;
//sigemptyset(&act.sa_mask);
//act.sa_flags=0;
//sigaction(SIGUSRR,&act,0);//設置信號SIGUSR1的處理方式忽略
usleep(1000000);
pthread_kill(threadId,SIGUSRR);
usleep(1000000);
pthread_kill(threadId,SIGUSRR);
usleep(2000000);
return0;
}
Ⅳ LINUX進程的非同步並發執行
fork出來的子進程和原父進程是並行的。
所以,在第一個父進程處fork出一個,然後在接下的代碼中,因為字進程也要接著從此處執行下去,
需要需要做判斷,這個判斷是為了區分父子進程,如何判斷?通過判斷PID。
因為你要產生2個子進程,不妨,第一個產生一個字進程,這個子進程再產生一個子進程,通過判斷PID,決定執行什麼代碼。
判斷PID的時候,父進程fork後,父子進程均取getpid這樣類似的函數,會發現,得到的值是不一樣的,這就可以判斷了。
Ⅳ linux 非同步i/o和信號驅動i/o的區別
這里假設你指的非同步I/O是針對的文件描述符,而信號驅動IO面向的是讀寫信號本身版。
比較典型權的例子是select和epoll的對比。使用select之前需要預先添加你所有感興趣的文件描述符,然後再遍歷這些文件描述符,找出其中有讀寫事件的fd,之後再對這些活躍的fd做處理。相比而言,epoll會高效得多:每當有一個fd的讀寫事件,內核則把該fd添加進一個事件列表,在使用的時候你只需要去取到這個事件列表(一個鏈表的數據結構)即可做相應操作。
這樣說來,就是上面說的,一個是掃描的文件描述符再判斷該文件描述符是否需要處理,這個是fd驅動;一個是直接取到有事件發生的文件描述符,也就是信號,或者說是事件驅動。
Ⅵ linux驅動模塊中添加非同步通知機制需要完成哪些工作
一 驅動方面:
1. 在設備抽象的數據結構中增加一個struct fasync_struct的指針
2. 實現設備操作中的fasync函數,這個函數很簡單,其主體就是調用內核的fasync_helper函數。
3. 在需要向用戶空間通知的地方(例如中斷中)調用內核的kill_fasync函數。
4. 在驅動的release方法中調用前面定義的fasync函數
呵呵,簡單吧,就三點。其中fasync_helper和kill_fasync都是內核函數,我們只需要調用就可以了。在1中定義的指針是一個重要參數,fasync_helper和kill_fasync會使用這個參數。
二 應用層方面
1. 利用signal或者sigaction設置SIGIO信號的處理函數
2. fcntl的F_SETOWN指令設置當前進程為設備文件owner
3. fcntl的F_SETFL指令設置FASYNC標志
完成了以上的工作的話,當內核執行到kill_fasync函數,用戶空間SIGIO函數的處理函數就會被調用了。
呵呵,看起來不是很復雜把,讓我們結合具體代碼看看就更明白了。
先從應用層代碼開始吧:
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <fcntl.h>
#include <signal.h>
#include <unistd.h>
#define MAX_LEN 100
//處理函數,沒什麼好講的,用戶自己定義
void input_handler(int num)
{
char data[MAX_LEN];
int len;
//讀取並輸出STDIN_FILENO上的輸入
len = read(STDIN_FILENO, &data, MAX_LEN);
data[len] = 0;
printf("input available:%s\n", data);
}
void main()
{
int oflags;
//啟動信號驅動機制,將SIGIO信號同input_handler函數關聯起來,一旦產生SIGIO信號,就會執行input_handler
signal(SIGIO, input_handler);
//STDIN_FILENO是打開的設備文件描述符,F_SETOWN用來決定操作是干什麼的,getpid()是個系統調用,
//功能是返回當前進程的進程號,整個函數的功能是STDIN_FILENO設置這個設備文件的擁有者為當前進程。
fcntl(STDIN_FILENO, F_SETOWN, getpid());
//得到打開文件描述符的狀態
oflags = fcntl(STDIN_FILENO, F_GETFL);
//設置文件描述符的狀態為oflags | FASYNC屬性,一旦文件描述符被設置成具有FASYNC屬性的狀態,
//也就是將設備文件切換到非同步操作模式。這時系統就會自動調用驅動程序的fasync方法。
fcntl(STDIN_FILENO, F_SETFL, oflags | FASYNC);
//最後進入一個死循環,程序什麼都不幹了,只有信號能激發input_handler的運行
//如果程序中沒有這個死循環,會立即執行完畢
while (1);
}
再看驅動層代碼,驅動層其他部分代碼不變,就是增加了一個fasync方法的實現以及一些改動
//首先是定義一個結構體,其實這個結構體存放的是一個列表,這個
//列表保存的是一系列設備文件,SIGIO信號就發送到這些設備上
static struct fasync_struct *fasync_queue;
//fasync方法的實現
static int my_fasync(int fd, struct file * filp, int on)
{
int retval;
//將該設備登記到fasync_queue隊列中去
retval=fasync_helper(fd,filp,on,&fasync_queue);
if(retval<0)
{
return retval;
}
return 0;
}
在驅動的release方法中我們再調用my_fasync方法
int my_release(struct inode *inode, struct file *filp)
{
//..processing..
drm_fasync(-1, filp, 0);
//..processing..
}這樣後我們在需要的地方(比如中斷)調用下面的代碼,就會向fasync_queue隊列里的設備發送SIGIO信號
,應用程序收到信號,執行處理程序
if (fasync_queue)
kill_fasync(&fasync_queue, SIGIO, POLL_IN);