unix/linux c函數接口大全

/*這個函數可以將errno直接轉換爲可讀的錯誤形式*/1)、char*    strerror(int errnum) 
/*這個函數將直接打印出errno當前值所對應的錯誤信息打印出來,參數可以指定一個字符串,函數將這個字符串顯示在錯誤信息前面*/2)、void     perror(const char* msg)
/*這個函數可以用來獲取主機名*/3)、int gethostname(char* name,size_t size)
/*這個函數可以設置主機名*/4)、int      sethostname(const char* name,size_t length)
/*這個函數將返回操作系統和主機的信息,保存在參數info裏面,那是一個結構體*/5)、int      uname(struct utsname *info)
//-|structure define|-
struct utsname{
    char    sysname[];//os
    char    nodename[];//host name
    char    release[];//os version
    char    release[];//os version level
    char    machine[];//hardware type
};
/*這個函數用於獲取系統當前系統變量之值,參數爲需要查看的系統變量*/6)、long int      sysconf(int parameter)
/*這個函數用來獲取文件系統限制和選項*/7)、long int   pathconf(const char* pathname,int parameter)
/*這個函數一樣用來獲取文件系統的限制和選項,只是需要提供的是文件描數字*/8)、long int   fpathconf(int filedes,int parameter)
/*這個函數可以獲得當前工作目錄*/9)、int        getcwd(char* buffer,size_t size)
/*這個函數用來打開一個文件流*/10)、FILE*   fopen(const char* pathname,const char* opentype)
/*這個函數用來關閉一個文件流*/11)、int     fclose(FILE* stream)
/*這個函數用來重新打開文件流*/12)、FILE*   freopen(const char* pathname,const char*opentype,FILE* stream)
/*這個函數用來讀取一個字符,並且強制轉換爲int*/13)、int     fgetc(FILE* stream)    
/*這個函數和fgetc一樣,只是可以作爲宏使用,而fgetc不可以*/14)、int     getc(FILE* stream)
/*這個函數相當於getc(stdin),也就是從標準輸入讀入*/15)、int     getchar(void)
/*這個函數將int c強制轉換爲unsigned char c,然後寫入stream*/16)、int     fputc(int c,FILE* stream)
/*可以用宏來實現,其他和fputc一樣*/17)、int     putc(int c,FILE* stream)
/*標準輸出,相當於putc(stdout)*/18)、int     putchar(int c)
/*這個函數將連續讀取count-1個字符,然後在末尾添加‘\0’,注意如果需要讀的字符多了,那麼就要多次調用*/19)、char*   fgets(char*s,int count,FILE* stream)
/*這個函數只從標準輸入讀取,功能和fgets一樣,只是一次讀完*/20)、char*   gets(char* s)
/*這個函數用來從流中讀入一行*/21)、ssize_t   getline(char** lineptr,size_t n,FILE* stream)
/*這個函數可以自己指定一次讀入的終止符,如果指定爲'\n',那麼就和getline一樣*/22)、ssize_t   getdelim(char** lineptr,int size_t n,int delimiter,FILE* stream)
/*每次輸出一行*/23)、int      fputs(const char* s,FILE* stream)
/*每次輸出一行到標準輸出*/24)、int      puts(const char* s)
/*該函數將一個字符回退到讀流中,所以下次讀的時候從這個字符開始,我們可以想象成是getc的逆操作*/25)、int     ugetc(int c,FILE* stream)
/*這個函數將從流中讀取指定個數的字符放在相應的位置,count爲數據項數,每項大小爲size,所以總大小爲size×count*/26)、size_t   fread(void* data,size_t size,size_t count,FILE* stream)
/*這個函數則可以寫到指定的流中count和size大小的數據*/27)、size_t   fwrite(const void* data,size_t size,size_t count,FILE* stream)
/*這個函數返回文件當前的位置,是從開始位置起的字節數,失敗返回-1*/28)、long int ftell(FILE* stream)
/*這個函數用於改變流的文件位置,whence+offset*/29)、int      fseek(FILE* stream,long int offset,int whence)
/*這個函數就是定位到文件的開始*/30)、void     rewind(FILE* stream)
/*這個函數將獲取文件的當前位置,保存在pos裏面*/31)、int       fgetpos(FILE* stream,fpos_t* pos)
/*這個函數用來設置流的位置*/32)、int       fsetpos(FILE* stream,fpos_t* pos)
/*這個函數將返回0,如果stream的錯誤指示器被設置*/33)、int      ferror(FILE* stream)
/*這個函數返回0,當且僅當文件末尾指示器被設置*/34)、int       feof(FILE* stream)
/*這個函數用來清除錯誤指示器和文件末尾指示器*/35)、void      clearerr(FILE* stream)
/*這個函數將打開一個文件描數字(也許創建)*/36)、int       open(const char* filename,int flag [,mode_t mode])
/*這個函數用來創建一個新的文件,等價於open(filename,O_WRONLY|O_CREAT|O_TRUNC,mode)*/37)、int       creat(const char* filename,mode_t mode)
/*這個函數將關閉一個文件描數字*/38)、int       close(int filedes)
/*從文件描數字讀*/39)、ssize_t    read(int filedes,void* buf,size_t nbytes)
/*向文件描數字寫*/40)、ssize_t    write(int filedes,const void* buf,size_t nbytes)
/*這個函數用來改變文件描數字的位置*/41)、off_t      lseek(int filedes,off_t offset,int whence)
/*這個函數將複製描數字old到新的描數字*/42)、int        dup(int old)
/*這個函數將old複製到new*/43)、int        dup2(int old,int new)
/*這個函數將使得一個文件描數字與一個流相連,函數返回這個文件描數字關聯的流*/44)、FILE*      fdopen(int filedes,const char* opentype)
/*這個函數將返回與一個文件流相連的文件描數字*/45)、int        fileno(FILE* stream)
/*這個函數可以實現對文件的各自操作,由參數cmd決定是什麼操作*/46)、int        fcntl(int filedes,int cmd,...)
/*這個函數可以實現散佈讀,將文件內容讀入到內存分散的緩衝區中,iovec是一個結構體,它擁有數據區的開始地址和大小*/47)、ssize_t    readv(int filedes,const struct iovec* iov,int iovcnt)
/*這個函數實現聚集寫,收集內存中分散的緩衝區中的數據寫至文件的連續區間,iovec是一個結構體,他擁有數據區的開始地址和大小*/48)、ssize_t    writev(int filedes,const struct iovec* iov,int iovcnt)
/*這個函數可以用來查看指定文件的特徵,返回鏈接所引用的文件的特徵*/49)、int       stat(const char* pathname,struct stat* buf)
/*這個文件用來查看指定文件的特診,返回鏈接本身的文件特徵*/50)、int       lstat(const char* pathname,struct stat* buf)
/*這個文件返回與文件描數字相連的文件特徵*/51)、int       fstat(int filedes,struct stat* buf)
/*這個函數實現鏈接文件,就是多個文件名錶示同一個文件,注意,只有一個inode,這是屬於硬鏈接的*/52)、int      link(const char* existingpath,const char* newpath)
/*這個函數實現符號鏈接,不直接指向inode,而是指向文件的路徑名,這個文件可以不存在*/53)、int        symlink(const char* path,const char* sympath)
/*這個函數則打開參數給定的符號鏈接文件,讀出內容放在相應的地方,然後關閉文件*/54)、int        readlink(const char* pathname,char* buf,int bufsize)
/*這個函數將改變文件的屬主id和組id,改變的是實際文件*/55)、int        chown(const char* pathname,uid_t owner,gid_t group)
/*這個函數改變文件的屬主id和組id*/56)、int        fchown(int filedes,uid_t owner,gid_t group)
/*這個函數用來改變文件的屬主id和組id,改變符號鏈接文件*/57)、int        lchown(const char* pathname,uid_t owner,gid_t group)
/*這個函數將設置進程的當前文件創建屏蔽,返回老的,不影響父進程*/58)、mode_t     umask(mode_t cmask)
/*這個函數用來改變文件的訪問方式,如果是符號鏈接,則改變的是指向的文件而不是本身*/59)、int        chmod(const char* filename,mode_t mode)
/*這個函數將改變文件的訪問方式,如果是符號鏈接,改變的是文件本身*/60)、int       fchmod(int filedes,mode_t mode)
/*這個函數用來測試一個用戶是否有權操作一個文件*/61)、int        access(const char* filename,int how)
/*這個函數用來截斷文件,使得一個已經存在的文件大小變爲指定長度的大小*/62)、int        ftruncate(int filedes,off_t length)
/*這個函數用來截斷文件,使得一個已經存在的文件大小變爲指定長度的大小*/63)、int        truncate(const char* pathname,off_t length)
/*這個函數用來改變文件的訪問時間和修改時間*/64)、int       utime(const char* pathname,const struct utimebuf* times)
/*這個函數頁用來改變文件的訪問時間和修改時間,數組第一個用來改變文件的訪問時間,第二個參數就是修改時間*/65)、int       utimes(const char* path,const struct timeval values[2])
/*這個函數將刪除一個文件名,並減少此文件的鏈接次數,如果計數爲0,那麼文件內容被刪除*/66)、int        unlink(const char* pathname)
/*這個函數將刪除一個目錄*/67)、int       rmdir(const char* pathname)
/*這個函數既可以用來刪除文件,也可以用來刪除目錄*/68)、int         remove(const char* pathname)
/*這個函數用來修改文件名和目錄名*/69)、int        rename(const char* oldname,const char* newname)
/*這個函數將得到進程的當前工作目錄*/70)、char*      getwd(char* pathbuf)
/*這個函數比較厲害,可以改變進程的工作目錄到指定的目錄,對父進程沒有影響*/71)、int        chdir(const char* pathname)
/*這個函數則實現和chdir一樣,只是參數不一樣*/72)、int        fchdir(int filedes)
/*這個函數將創建一個目錄*/73)、int         mkdir(const char* pathname,mode_t mode)
/*目錄也是一種文件,所以可以讀目錄流,該函數是第一步,即打開目錄,返回指向其DIR的指針*/74)、DIR*        opendir(const char*  dirname)
/*這個函數讀取目錄DIR中的一個目錄,而且使得指向下一項*/75)、struct dirent* readdir(DIR* dirp)
/*函數關閉一個目錄流*/76)、closedir(DIR* dirp)
/*該函數將恢復dirp所指向的目錄流指向第一項目錄*/77)、void      rewinddir(DIR* dirp)
/*該函數返回目錄當前位置*/78)、long int      telldir(DIR* dirp)
/*設置目錄位置,參數loc應該是telldir返回的結果*/79)、void   seekdir(DIR* dirp,long int loc)
/*這是環境表指針,其中的內容形如name=value*/80)、extern char** environ;
/*這個函數將返回指定名字的環境的值*/81)、char*      getenv(const char* name)
/*該函數可以用來設置一個環境變量或者去掉一個環境變量*/82)、int        putenv(char* str)//the str just like=>name=value
/*這個函數將終止進程*/83)、void       exit(int status)
/*這個函數將流產進程,因爲該函數將生成一個轉儲文件*/84)、void      abort()
/*這個函數將實現動態分配內存*/85)、void*     malloc(sise_t size)
/*這個函數和malloc一樣,只是常用來爲結構體分配內存*/86)、void*     calloc(size_t num_of_elem,size_t ele_size)
/*這個函數用來重新分配村內,需要十分小心的使用*/87)、void*     realloc(void* ptr,size_t newsize)
/*這個函數釋放動態分配的內存*/88)、void      free(void* ptr)
/*這個函數將獲得進程的資源限制,resource 參數指明那種資源*/89)、int       getrlimit(int resource,struct rlimit* rlptr)
/*這個函數用來設置進程資源限制,resources指明要設置哪種資源*/90)、int       setrlimit(int resource,const struct rlimit* rlptr)
//-|structure define|-
struct rlimit{
     rlim_t   rlim_cur;//current limit
     rlim_t   rli_max;//max (machine) lmit
};
/*這個函數用來獲取進程的資源使用情況,比如用了多少cpu,缺頁次數等等*/91)、int       getusage(int who,struct rusage* rusage)
//-|structure define|-
struct rusage{
    struct timeval ru_utime;//run user instructions
    struct timeval ru_stime;//run os with process
}
//-|structure define|-
struct timeval{
       time_t   tv_Sec;
       suseconds  tv_usec;
}
/*這個函數將返回用戶名*/92)、char*     getlogin()
/*這個函數將返回進程的實際用戶id*/93)、uid_t     getuid()
/*這個函數將返回進程的有效用戶id*/94)、uid_t     geteuid()
/*函數將返回進程的實際組id*/95)、gid_t     getgid()
/*函數返回進程的有效組id*/96)、gid_t     getegid()
/*獲取進程id和父進程id*/97)、pid_t     getpid()|getppid()
/*創建進程*/98)、pid_t    fork()//返回0表示是子進程,其他表示父進程

/*這個函數將等待進程完成*/99)、pid_t   wait(int *stat_loc)|pid_t  waitpid(pid_t pid,int* stat_loc,int options)
/*這個函數將執行一個新程序*/100)、int    system(const char* command)
/*這個函數將信號數signo對於的描述信息,如果msg不是空指針的話,那麼函數將用這個msg作爲前綴輸出*/101)、void   psignal(int signo,char* msg)
/*這個函數將簡單的發送一個信號給調用他的進程*/102)、int   raise(int signo)
/*這個函數將發送一個信號給一個進程或者一個進程組,sig指明要發送的信號*/103)、int   kill(pid_t  pid,int sig)
/*我們當然可以設置信號的動作,所以下面這個函數用來設置信號發生時的動作,[void(*sighandler_t)(int)]*/104)、sighandler_t  signal(int signum,sighandler_t handler)
/*還有一個函數可以設置信號動作,這個函數將更加安全*/105)、int  sigaction(int signum,const struct sigaction* act,struct sigaction* oact)
//-|structure define|-
struct sigaction{
    void   (*sa_handler)();
    void   (*sa_sigaction)(int,siginfo_t*,void*);
    sigset_t    sa_mask;
    int         sa_flags;
};
//--set--  下面這些函數完成信號集操作106)、int  sigemptyset(sigset_t* set) //將set清空107)、int  sigfillset(sigset_t* set)//使得set包含所有信號,和sigemptyset是相反的108)、int  sigaddset(sigset_t* set,int signo) //將信號signo加到set集合裏面去109)、int  sigdelset(sigset_t* set,int signo) //將信號signo從set裏面移除110)、int  sigismember(const sigset_t*set,int signo) //查看signo信號是不是在信號集合set裏面
/*該函數將設置進程想要阻塞的信號*/111)、int  sigprocmask(int how,const sigset_t* set,sigset_t* oset)
/*已經發生但是還未交付的信號稱爲懸掛信號,我們可以用這個函數來檢測是否有懸掛信號,參數就是返回的懸掛信號集合*/112)、int  sigpending(sigset_t* set)
/*這個函數用來等待信號,簡單的懸掛進程知道信號到達*/113)、int  pause()
/*這個函數將更加高級,可以指定那些我們不關心的信號,所以只有當出現不包含在參數信號集合裏面的信號時,纔會喚醒進程*/114)、int   sigsuspend(const sigset_t* sigmask)
/*這個函數將返回unix紀元(總秒數),如果loc是非空指針,那麼loc裏面也將會有一個副本*/115)、time_t  time(time_t* loc)
/*這個函數將計算兩個時間之間的差,結果作爲雙精度浮點返回*/116)、double  difftime(time_t time1,time_t time2)
//--set-- 下面的函數將是以微妙爲單位的117)、int   gettimeofday(struct timeval* restrict tp,void* restrict tzp)//將返回描述和微妙數在第一個參數裏面,我們不需要知道第二個參數(時區)118)、int   settimeofdat(const struct timeval* tp,const void* tzp) //這個函數將設置當前時間爲tp,當然只有特權用戶纔有這樣的資格119)、int   adjtime(const struct timeval* delta,struct timeval* olddelta) //對時鐘做微調,如果爲負數,則系統將走慢一點直到過去那麼多時間
//--set--  下面這組函數是對上面函數的操作,也就是將描述或者微妙數轉換爲tm結構120)、struct tm* gmtime(const time_t* time) //你需要提供一個time_t類型的指針,函數將這個指針所指向的時間轉換爲tm121)、struct tm* localtime(const time_t* time) //這個函數將time轉換爲本地時間,很複雜,但是使用很簡單122)、time_t     mktime(struct tm* brokentime) //這個函數將tm結構的時間轉換爲time_t類型
//--set--  unix提供了可以將tm或者time_t時間轉換爲可讀的形式的函數123)、char*       asctime(const struct tm* timeptr) //將timptr轉化爲可讀的形式返回124)、char*       ctime(const time_t* timeval) //將timeval轉換爲可讀的形式返回
//--comment-- cpu時間和牆鍾時間,cpu時間也就是進程實際佔用cpu運行的時間,而牆鍾時間則是從進程開始便開始計時的
//--comment-- 所以牆鍾時間可能包含有其他進程運行的時間,當然,cpu時間又分爲用戶時間和系統時間,用戶時間就是cpu執行
//--comment-- 用戶指令的時間,而系統時間就是系統爲執行進程而運行的一些時間,比如系統調用時間

/*這個函數將返回進程當前的cpu時間,包括用戶時間和系統時間*/125)、clocl_t   clock()   //clock_t 表示系統內部使用的時間單位,爲了將返回時間變爲秒,需要除以CLOCK_PER_SEC
/*這個函數報告更加詳細的cpu時間,包括自己用去的時間,系統爲自己服務用去的時間,子進程的時間,同時還返回系統當前的牆鍾時間*/126)、clock_t  times(struct tms* buff)
//-|structure define|-
struct tms{
     clock_t   tms_utime;//user cpu time
     clock_t   tms_stime;//system cpu time
     clock_t   tms_cutime;//child user cpu time
     clock_t   tms_cstime;//child system cpu time
}
/*這個函數將使得進程睡眠一段時間,它掛起調用進程直到發生下面的事情:(1)、時間到(2)、信號到*/127)、unsigned int sleep(unsigned int seconds) //注意,參數單位是秒,不是微妙
/*這個函數用來設置一次性的定時,只能設置牆鍾時間,到期會生成SIGALRM信號,如果進程沒有捕捉該信號,默認會結束該進程*/128)、unsigned int alarm(unsigned int seconds)
//--set-- 下面的函數可以用來設置或者獲取三種定時器129)、int  setitimer(int which/*whick clock*/,const struct itimeval*value,struct itimerval* ovalue)
(130)、int  getitimer(int which,struct itimerval* value)
//-|structure define|-
struct itimerval{
     struct timeval  it_interval;//定時器的間隔時間
     struct timeval  it_value;//定時器的開始時間
}
//--comment-- 關於實時時鐘,系統定義的實時時鐘有幾種類型,可以查看相關內容
//-|structure define|-
struct timespec{
     time_t   tv_sec;//秒數
     long     tv_nsec;//不足一秒的納秒數
};
//--set-- 下面的函數將用來獲取或者設置實時時鐘131)、int   clock_getres(clockid_t clock_id,struct timespec* res) //該函數將返回指定時鐘的分辨率,保存在res裏面132)、int   clock_gettime(clockid_t clock_id,struct timespec* tp) //返回指定實時時鐘的時間,保存在tp裏面133)、int   clock_settime(clockid_t clock_id,const struct timespec* tp) //設置實時時鐘,只有特權用戶可以
/*一種時間更短的睡眠*/134)、int nanosleep(const struct timespec* res,struct timespec* rem) //睡眠res時間,如果有信號來了,將剩餘時間保存在rem裏面
//--comment-- 實時定時器,分辨率更高
//-|structure define|-
struct itimerspec
{
     struct timespec it_value;//定時開始時間
     struct timespec it_interval;//定時間隔
}

//--set-- 下面的函數將實現創建和刪除實時定時器135)、int   timer_create(clockid_t clockid,struct sigevent* restrict evp/*action*/,timer_t *restrict timerid/*id of timer*/)
(136)、int   timer_delete(timer_t timeid) //delete a timer

//--set-- set and get timer137)、int   timer_gettimer(timer_t timeid,struct itimerspec* value) //get138)、int   timer_settimer(timer_t timeid,int flags,const struct itimerspec* restrict value,struct itimerspec* restrict ovalue)
(139)、int   timer_getoverrun(timer_t timeid) //返回定時器的超時次數
/*這個函數在前面已經有介紹,但是這裏作爲設置文件鎖而特別指出*/140)、int    fcntl(int fildes,int cmd,struct flock* lock)
/*
   關於信號驅動的IO:採用信號驅動的IO,則當在描數字上有數據到達時,進程會收到一個信號,此時對
   該描數字進行輸入輸出操作將不會被阻塞。
   下面是實現信號驅動的IO的步驟:
   (1)、調用sigaction函數來建立信號句柄
   (2)、調用fcntl函數用F_SETOWN來設置接收信號的進程或者進程組
   (3)、如果要接收的信號是SIGIO,需要調用fcntl函數用F_SETTFL命令設置文件描數字的O_ASYNC標誌使其能夠生成SIGIO信號
*/
/*下面這個函數功能很強大,他告訴內核,需要等待多種IO事件,只有當這些中的一個或者多個出現時,或者指定的時間過去時,才喚醒調用他的進程*/141)、int select(int nfds,fd_set* rfds,fd_set* wfds,fd_set* efds,struct timeval* timeout)
/*
    關於上面這個函數,函數將返回已經就緒的描數字的個數,或者超時出返回-1
    我們可以用下面的宏定義來查看一些細節:
    void FD_ZERO(fd_Set* fdset)    //初始化爲空
    void FD_CLR(int filedes,fd_Set* fdset) //將filedes從fdset裏面清除
    void FD_ISSET(int filedes,fd_set* fdset) //屬於嗎
    void FD_SET(int filedes,fd_set* fdset) //加入
*/
/*下面這個函數和select函數一樣,檢查一組文件描數字,查看是否有任何懸掛的事件,並且可以有選擇的爲某個描數字上的時間設定時間*/142)、int poll(struct pollfd fds[],nfds_t nfds,int timeout)
//-|structure define|-
struct pollfd{
    int fd;//要檢查的描數字
    short events;//感興趣的事情
    short revents;//fd上發生的事情
};

/*
   * events 是用戶對這個文件描數字上感興趣的事情,而revents是這個文件描數字上實際發生的事件。
   * 也就是函數的返回值,最後一個參數爲最長的等待時間,單位時毫秒
*/

/*下面這個函數可以將一個文件映射到內存,應當首先用open打開,然後調用下面這個函數*/143)、void* mmap(void* addr,size_t len,int prot,int flags,int filedes,off_t off)
///--- 上面函數實現將指定文件描數字filedes中的文件的[off,off+len]區間映射到進程的內存
///--- [paddr,paddr+len]區間,paddr是函數的返回值。也就是最終的映射到進程的開始地址
///--- 那麼addr是什麼玩意呢?也就是自己指定映射的開始位置,如果爲0,那麼內核將找到合適的
///--- 位置然後告訴進程我把文件映射到了哪裏!
///--- 其中,prot是映射區的保護權限,應該和open時指定的權限一致。
///--- flags是映射區的屬性,必須要麼是共享的,要麼是私有的,還可以加上是否必須返回addr

/*當然,有映射自然會有解映射,下面這個函數是,mmap的相反函數*/144)、int  mumap(void* paddr,size_t len)
///--- paddr應該是mmap返回的結果,len是映射區的長度。

/*對於屬性爲共享的存儲映射區,當映射區的一頁被修改時,會被存回硬盤,如果想要在程序的某個點將其中的內容寫到磁盤,下面這個函數可以*/145)、 int  msync(void* addr,size_t len,int flags)
///--- flags參數控制寫回這片區域的執行方式,可以取下面三個
///---  MS_ASYNC  -->異步執行
///---  MS_SYNC   -->同步執行,完成函數纔會返回
///---  MS_INVALIDATE  -->作廢與指定映射區中的數據不一致的緩存副本

/*下面這個函數用來創建一根管道,函數將返回兩個文件描數字,分別是管道的輸入輸出端*/146)、int  pipe(int fildes[2])
///--- fildes[0] 將設置爲讀而打開,dildes[1]將設置爲寫而打開
///--- 管道是沒有名字的,所以叫做匿名管道

/*下面這個函數關於在調用進程與要執行的命令之間建立一個內部的半雙工的管道,然後派生一個子進程,執行command命令*/
///--- 需要注意是,這和system函數還是有區別的,system函數將等待執行完成再返回,而該函數將立即返回147)、FILE* popen(const char* command,const char* mode)
/*用popen打開的管道需要用下面的函數來關閉*/148)、int  pclose(FILE* stream)
///--- 管道只能用於父子進程之間的通信,因爲管道建立在內核之中,只有那些有遺傳關係的進程才能用到它
///--- FIFO特別文件可以在非父子關係的進程之間實現數據交換
///--- 對於FIFO特別文件來說,只要文件被打開,他的行爲就和管道是一樣的。
///--- 在進行通信之前,需要有一個進程以讀打開這個fifo文件,另一個進程以寫打開這個fifo特別文件
/*這個函數將創建一個名字爲filename的fifo文件*/149)、int   mkfifo(const char* filename,mode_t mode)
/*這個函數更加強大,不僅可以創建fifo文件,還可以創建其他的文件,文件類型由mode給出*/150)、int  mknod(const char* filename,mode_t mode,dev_t dev)
/*下面這個函數可以用來創建獲得消息隊列,函數調用成功會返回與key相連的id,我們可以用id來訪問消息隊列*/151)、int  msgget(key_t key,int flags)
/*消息隊列的查詢、設置和刪除*/152)、 int msgctl(int msqid,int cmd,struct msqid_ds* buf)
///--- cmd 就是我們想要做的事情,可以取下面的值---
///--- IPC_STAT --> 複製消息隊列的內核數據結構到buf裏面 
///--- IPC_SET -->用buf裏面的值設置消息隊列
///--- IPC_RMID --> 刪除指定的消息隊列

/*下面這個函數實現向一個消息隊列發送消息*/153)、 int msgsnd(int msqid,const void* msgp,size_t msgze,int msgflg)
///--- 第一個參數是消息隊列的id,第二個參數是指向消息緩衝區的指針,第三個參數給出消息緩衝區的消息正文的字節數
///--- 不包括消息類型成員(第一個成員),最後一個參數用來引導當進程阻塞時的動作

/*下面這個函數用來接收消息*/154)、ssize_t msgrcv(int msqid,void* msgp,size_t msgsz,long int msgtyp,int msgflg)
///---這個函數從消息隊列msqid裏面讀消息到msgp裏面,msgsz指出消息正文的字節數,msgtyp指明要接收的消息類型
///--- --> =0 接收消息隊列裏面的第一個消息
///--- --> >0 接收類型等於msgtyp的第一個消息,這種方式可實現只接收特定類型的消息
///--- --> <0 接收類型小於或者等於msgtyp絕對值的第一個最低類型的消息,實現優先級

/*下面這個函數將實現創建和獲得共享存儲段*/
(155)、int shmget(key_t key,size_t size,int shmflg)
/*共享存儲段的查詢、設置、刪除*/
(156)、int   shmctl(int shmid,int cmd,struct shmid_ds* buf)
/*創建好了共享存儲段之後,我們還需要將它映射到進程的地址空間,下面這個函數可以實現這個功能*/
(157)、void* shmat(int shmid,const void* shmaddr,int shmflg)
///--- 溫馨提示:爲了簡單,shmaddr就讓他等於0吧,剩下的事情讓操作系統爲你完成
/*創建和獲得信號量*/
(158)、int  semget(key_t key,int nsems,int semflg)
///--- nsems指明信號量集合中信號量的個數
/*信號量的查詢、設置、刪除*/
(159)、int semctl(int semid,int semnum,int cmd,[union semun arg])
///--- semid是信號量集合的標誌,semnum指明一個特定的信號量
/*信號量操作*/
(160)、int semop(int semid,struct sembuf* sops,size_t nsops)
///--- 該函數對指定的semid信號量集合進行操作,操作既可以對其中的一個信號量,也可以針對整個信號量還可以
///--- 是等待信號量,sops給出操作類型
//-|structure define|-
struct sembuf
{
    unsigned short int sem_num;//信號量編號
    short int sem_op;//信號量操作
    short int sem_flg;//信號量標誌
}

///--- sem_op
///--- <0   減少一個信號量,減少的值爲abs(sem_op),當爲-1時,相當於P操作
///--- >0   增加一個信號量,增加的值爲sem_op,當爲1時,相當於V操作
///--- ==0  等待信號量變爲0 
///--- 注意:semop()函數調用只有當集合中所有信號量都能成功時才成功返回,如果某個信號量不能完成,失敗!


//套接字等價於網絡,就好像文件描數字是磁盤描述的一個端口一樣。我們可以用下面的函數來創建一個網絡套接字161)、int  socket(int domain,int type,int protocol)
///---socket 將和文件描數字一樣會返回最小的還沒有被使用的套接字描數字
///---第一個參數domain指明通信域:可以爲AF_UNIX,AF_INET,AF_INET6
///---第二個參數是套接字的類型,可以爲:SOCK_STREAM,SOCK_DGRAM,SOCK_RAW.
///---對於第三個參數,只要前兩個參數確定了,就可以確定第三個參數也就是協議了,所以只需要填0就可以了

/*下面的函數可以實現同時創建一對套接字描數字,是全雙工的*/162)、int socketpair(int domain,int type,int protocol,int filedes[])

/*下面這個函數用來關閉一個已經打開的套接字描數字,黨我們關閉了一個套接字之和,這個套接字便不再存在*/163)、int close(int socket)
/*當我們這是想斷開連接而不是關閉一個套接字,那麼可以用下面這個函數來實現*/164)、int shutdown(int socket,int how)
///---這個函數將部分或者全部斷開套接字socket的連接,取決於how的值是什麼
///---SHUT_RD:停止從該套接字接收數據
///---SHUT_WR:停止從該套接字傳送數據
///---SHUT_RDWR:停止從該套接字傳輸和接收數據

/*下面這組函數將實現ip地址的格式轉換,可以從二進制形式轉換爲點分十進制形式,也可以向相反的方向轉換*/165)、int inet_aton(const char* name,struct in_addr* addr) //從字符串轉換到二進制(32位),保存在addr裏面166)、char* inet_ntoa(struct in_addr* addr)//將32位的ip地址轉換爲字符串形式167)、int  inet_pton(int family,const char*nameptr,void* addrptr) //將可以用在ipv4上,也可以用在ipv4上168)、const char* inet_ntop(int family,void* addptr,char* nameptr,size_t len) 

//在unix裏面,用了一個主機網絡地址數據庫來記住主機名和主機ip地址之間的映射
//我們可以用下面的函數來從這個數據庫中獲得一臺主機的完整地址信息168)、struct hostent* gethostbyname(const char* name) 
(169)、struct hostent* gethostbyaddr(const void* addr,size_t length,int type) //length is the len of addr,the type is the type of addr

/*我們可以用下面的這個函數來打開地址數據庫,當參數爲不爲0時,將會和數據庫建立持久連接*/170)、void sethostent(int stayopen)
(171)、struct hostent* gethostent();
(172)、void endhostent(); //關閉數據庫

///--我們知道有一些默認的應用是綁定到了固定的端口上的,比如21號端口就是用來進行FTP服務的,我們
///---可以通過下面的函數來查看一些著名的服務173)、struct servent* getservbyname(const char* name,const char* proto)
(174)、struct servent* getservbyport(int port,const char* proto)
(175)、void setservent(int stayopen)
(176)、struct servent* getservent();
(177)、void endservent()

///---下面是很煩很無聊的字節順序轉換,在網絡上操作的話都要轉換爲網絡字節順序178)、uint_16_t  htos(uint_16_t hostshort)
(179)、uint_32_t  htol(uint_32_t hostlong)
(180)、uint_16_t  stoh(uint_16_t hostshort)
(181)、uint_32_t  ltoh(uint_32_t hostlong)

///---好吧,現在我們應該會創建一個套接字描數字,然後也瞭解了ip地址,套接字等內容,下面我們需要給套機字一個名字
///---當套接字有了名字之和,我們就可以使用套機字名字來操作這個套機字了,也就是說,套機字沒有名字,其他進程根本
///---無法訪問到這個沒有名字的套接字,所以我們需要給他一個名字,下面這個函數可以實現將一個套接字綁定在一個名字上182)、int bind(int socket,const struct sockaddr* address,socklen_t address_len)

///---現在我們先來了解一下套機字是怎麼工作的:首先用socket函數創建一個套接字描數字,然後調用bind函數來給
///---這個套接字綁定一個名字,以便其他進程可以訪問這個套接字。然後用listen來監聽這個套接字上的活動,在多個
///---客戶與該套接字建立連接的情況下,listen函數爲進入該套接字的連接創建一個連接隊列,然後調用accept函數
///---逐一處理這些連接,需要知道的是,每次調用accept函數,系統都將創建一個新的套接字,但是這個新的套接字將
///---只用於與特定的客戶連接,所以不需要命名,那已經命名的套接字保留用於與其他用戶連接,這樣就可以實現
///---一個套接字描數字和多個客戶通信的需求了---->以上言論對有連接的套接字通信有效
///---對於無連接的套接字通信,事情變得很簡單,他使用對等的方式來進行數據交換,但是依然需要bind一個名字
///---然後事情就在recvfrom和sendto這兩個函數之間變得有趣了!

//下面這個函數是對於流套接字操作而言的,而且這個函數用於客戶端請求與服務端建立一個連接183)、int connect(int socket,const struct sockaddr* address,socklen_t address_len)

//下面函數可以在套接字上創建偵探隊列,成功後這個套接字將稱爲被動套接字,也就是服務套機字184)、int listen(int socket,int backlog) //backlog指明該套接字上可以懸掛的請求連接數

//下面函數將會創建一個新的套機字來爲客戶服務,函數將返回新套接字的描數字,後兩個參數將作爲返回185)、int accept(int socket,struct sockaddr* address,socklen_t* address_len)

//兩個套接字建立連接之和,我們可以通過下面的函數來查看對方套機字地址和本地套機字地址186)、int getsockname(int socket,struct socketaddr* address,socklen_t* address_len)  //獲取本地187)、int getpeername(int sock,struct sockaddr* address,socklen_t* address_len) //獲取對方的

/*我們應該知道,套接字也是一種文件,所以可以像操作文件一樣操作套接字,write和read可以用來從一個套接字讀取數據和發送數據*/
///---下面的函數也可以實現向一個套接字發送數據或者從套接字讀取數據188)、ssize_t  send(int socket,const void* buffer,size_t length,int flags)
///---需要注意的是最後一個參數,如果最後一個參數爲0,那麼就和write一樣了,當然這個標誌可以取下面的值
///---MSG_OOB:使得send發送的數據稱爲帶外數據
///---MSG_DONTROUTE:不再消息中包含路由信息189)、ssize_t recv(int socket,void* buffer,size_t length,int flags)
///---最後一個參數要是取0的話,和read是一樣的
///---MSG_PEEK:窺視套接字上的數據但是不讀取他們
///---MSG_OOB:讀帶外數據
///---MSG_WAITALL:函數將阻塞直到讀到所請求的全部數據

/*下面的函數將可以查看和設置套接字的各自選項*/190)、int  getsockopt(int socket,int level,int optname,void* optval,socklen_t* optlen)
(191)、int  setsockopt(int socket,int level,int optname,const void* optval,socklen_t optlen)

///---需要注意的是,參數socket需要是已經打開的套接字,level指出所選擇的層次,可以是下面的值
///---SOL_SOCKET,IPPOTO_IP,IPPOTO_TCP
///---optname指出選項的名字,對於getsockopt來說,函數將讀取名字爲optname的選擇,將讀出來的值
///---保存在optval裏面,對於設置來說,需要自己指定optval
///---選項可以查看相應的文檔獲得

/*下面這個函數可以判斷當前是否處在帶外數據標誌的位置*/192)、int sockatmark(int sockfd)
///---(1)、當下一個要讀的字節是oob時,函數返回真
///---(2)、讀操作總是停止在帶外數據標誌之處

/*下面這兩個函數可以實現對數據報套接字的數據發送與接收*/193)、int recvfrom(int socket,void* buffer,size_t size,int flags,struct sockaddr* from,size_t* addrlen)
(194)、int sendto(int socket,void* buffer,size_t size,int flags,struct sockaddr* to,size_t addrlen)

///---需要特別說明,數據報套接字也可以使用connect函數,但是對於數據報套接字來說這個函數並不會建立連接
///---而只是給將來在此套接字上的傳送指定地址,內核將記錄對等套接字的ip地址和端口,這樣我們就可以不用
///---recvfrom和sendto函數了,可以使用read或者recv或者write或者send函數了

/*下面的函數可以查看一個線程自己的線程id,需要知道的是線程也有線程id,而且在一個進程裏面的每一個線程都具有不一樣的線程id*/195)、pthread_t  pthread_self()

/*下面這個函數可以用來比較倆個線程id,兩個線程id相同時返回非0,不同時返回0*/196)、int pthread_equal(pthread_t t1,pthread_t t2)

/*下面這個函數用來創建一個新的線程*/197)、int pthread_create(pthread_t *restrict thread,const pthread_attr_t* restrict attr,
  void*(*start_routine)(void*),void* restrict argv)

  ///---每一個進程一開始就會有一個線程,稱爲初始線程,或者叫做主線程,他是從main函數開始的,進程中的其他
  ///---線程在創建線程時指定一個線程開始函數,這個線程開始函數只能有一個void*的參數,這個新創建的線程將
  ///---從這個函數開始執行
  ///--第一個參數是函數的返回值,函數調用成功將返回這個新創建的線程的id,第二個參數指定新創建的線程的屬性

  /*下面這個函數將終止線程,也就是終止自己的執行*/198)、int pthread_exit(void* value_ptr)

  ///---參數應該是一個出口狀態,當其他的線程在等待這個線程時,當這個線程結束時,其他等待該線程的線程將會得到這個
  ///---線程出口狀態,然後做下一步的動作

  /*下面這個函數用來等待一個線程終止*/199)、int pthread_join(pthread_t thread,void** value_ptr)

  ///---該函數將懸掛調用該函數的線程直到所等待的線程終止,第二個參數將保存從等待線程返回的出口狀態,該
  ///---線程可以根據這個出口狀態來執行相應的函數

  ///---關於可匯合線程和分離線程
  ///---可匯合線程:線程的資源需要另一個線程調用pthread_join與他匯合之後才能被釋放
  ///---分離線程:線程一旦終止,系統將立刻回收他的資源

  /*下面的函數可以將原本可匯合的線程變爲分離的線程,需要知道的是,默認創建的線程都是可匯合的*/200)、int  pthread_detach(pthread_t thread)
  ///---已經分離的線程不能和其他線程匯合,所以一旦一個線程被設置爲分離的,那麼這個線程就不能被pthread_join

  /*下面的一組函數用來設置特殊屬性的線程*/

  ///---線程的一般屬性包括:分離狀態屬性,棧的大小,棧地址,棧溢出保護區大小,調度屬性,調度的競爭範圍,調度的繼承屬性
  ///---調度策略,調度參數201)、int  pthread_attr_init(pthread_attr_t *attr) //初始化一個線程屬性202)、int  pthread_attr_destroy(pthread_attr_t* attr) //銷燬一個線程屬性對象203)、int  pthread_attr_getdetachstate(pthread_attr_t* attr,int* detachstate) //查詢線程屬性對象的分離狀態,將返回在第二個參數裏面204)、int  pthread_attr_setdetachstate(const pthread_ttr_t* attr,int detachstate) //設置線程屬性屬性對象的分離狀態

  ///---下面是互斥變量的初始化和銷燬205)、pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER;
  (206)、int  pthread_mutex_init(pthread_mutex_t *restrict mutex,const pthread_mutexattr_t* restrict attr) //初始化207)、int  pthread_mutex_destroy(pthread_mutex_t *mutex)

  ///---互斥變量也是有屬性的,現在有兩種屬性,一種是進程共享屬性,和類型屬性
  ///---共享屬性設置一個互斥鎖是否可以在進程之間使用
  ///---下面的函數是和互斥變量屬性相關的函數208)、int  pthread_mutexattr_init(pthread_mutexattr_t * attr) //初始化一個互斥變量屬性209)、int  pthread_mutexattr_destroy(pthread_mutexattr_t* attr) //銷燬一個互斥變量屬性

  ///---下面兩組函數可以用來設置互斥變量的進程共享屬性和類型屬性210)、int pthread_mutexattr_setpshared(pthread_mutexattr_t* attr,int pshared) //設置進程共享屬性211)、int pthread_mutexattr_getpshared(pthread_mutexattr_t* attr,int *restrict pshared) //查看互斥變量的進程共享屬性212)、int pthread_mutexattr_settype(pthread_mutexattr_t* attr,int pshared) //設置互斥變量類型屬性213)、int pthread_mutexattr_hettype(pthread_mutexattr_t* attr,int * restrict type)


  ///--下面的函數用來對互斥變量加鎖或者解鎖214)、int pthread_mutex_lock(pthread_mutex_t* mutex) //上鎖,但是如果失敗,等待直到獲得鎖才返回215)、int pthread_mutex_trylock(pthread_mutex_t* mutex)//如果上鎖失敗的話,立刻返回錯誤<EBUSY>216)、int pthread_mutex_unlock(pthread_mutex_t* mutex)//解鎖


  ///---下面的函數是和spin鎖相關的函數,操作和理解方式和互斥鎖一樣217)、int pthread_spin_init(pthread_spinlock_t * lock,int pshared) //初始化一個spin218)、int pthread_spin_destroy(pthread_spinlock_t* lock)
  (219)、int pthread_spin_lock(pthread_spinlock_t* lock)
  (220)、int pthread_spin_trylock(pthread_spinlock_t* lock)
  (221)、int pthread_spin_unlock(pthread_spinlock_t* lock)

  ///---需要注意的是,spin鎖和互斥鎖還是不一樣的,當上鎖受阻時,線程不需要阻塞而是可以輪詢直到獲得鎖


  ///---下面的函數是關於讀寫鎖的
  ///---讀寫鎖支持線程對數據的共享讀互斥寫
  ///---可以以讀方式上鎖,一個線程佔有這個鎖之後,還是允許其他的線程來以讀的方式上鎖
  ///---可以以寫方式上鎖,一個線程佔有這個鎖之後,不允許其他的鎖進來222)、pthread_rwlock_t rwlock=PTHREAD_RWLOCK_INITIALZER;
  (223)、int pthread_rwlock_init(pthread_rwlock_t* restrict rwlock,const pthread_rwlockattr_t* attr)
  (224)、int pthread_rwlock_destroy(pthread_rwlock_t* rwlock)
  ///---需要注意的是,讀寫鎖只有一種屬性,可以指定爲進程之內或者是進程之間
  ///---下面的函數是關於讀寫鎖屬性的函數225)、int pthread_rwlockattr_init(pthread_rwlockattr_t* attr)
  (226)、int pthread_rwlockattr_destroy(pthread_rwlockattr_t* attr)
  (227)、int pthread_rwlockattr_setpshared(pthread_rwlockattr_t* attr,int pshared)
  (228)、int pthread_rwlockattr_getpshared(pthread_rwlockattr_t* attr,int pshared)


  ///---下面的函數是關於讀寫鎖的上鎖和解鎖的229)、int pthread_rwlock_rdlock(pthread_rwlock_t* rwlock) //以讀方式上鎖,如果不能獲得鎖,那麼受阻直到獲得鎖230)、int pthread_rwlock_tryrdlock(pthread_rwlock_t* rwlock) //如果線程不能立刻獲得鎖的話,那麼這個函數將會返回EBUSY<立刻>231)、int pthread_rwlock_wrlock(pthread_rwlock_t* rwlock) 
  (232)、int pthread_rwlock_trywrlock(pthread_rwlock_t* rwlock)

  ///---無論讀寫鎖是怎麼加的鎖,下面這個函數都可以解開234)、int pthread_rwlock_unlock(pthread_rwlock_t* rwlock)


  ///---關於條件變量
  ///---下面的函數是關於初始化和銷燬條件變量的235)、pthread_cond_t cond=PTHREAD_COND_INITIALZER;
  (236)、int pthread_cond_init(pthread_cond_t* cond,pthread_condattr_t* attr)
  (237)、int pthread_cond_destroy(pthread_cond_t* cond)

  ///---條件變量的屬性操作函數集合238)、int pthread_condattr_init(pthread_condattr_t* attr)
  (239)、int pthread_condattr_destroy(pthread_condattr_t* attr)
  (240)、int pthread_condattr_setpshared(pthread_condattr_t* attr,int * pshared)
  (241)、int pthread_condattr_getpshared(pthread_condattr_t* attr, int * pshared)


  ///---等待條件變量
  ///---一個是執行正常的等待操作,一個是指定定時的等待操作242)、int pthread_cond_wait(pthread_cond_t* cond,pthread_mutex_t* mutex)//mutex是與條件變量相關連的互斥變量243)、int pthread_cond_timedwait(pthread_cond_t* cond,pthread_mutex_t* mutex,struct timespec* abstime)
  ///---需要注意的是,調用這兩個函數之前mutex必須處於鎖住的狀態,在這兩個函數阻塞之前,函數將會釋放mutex

  ///---喚醒條件變量的等待,可以有兩種方式來喚醒,一種是每次喚醒一個線程,稱爲“發信號”
  ///---另一種則一次喚醒等待在同一個條件變量上的所有線程,這種方式稱爲“廣播”244)、int pthread_cond_signal(pthread_cond_t* cond)
  (245)、int pthread_cond_broadcast(pthread_cond_t* cond)
  ///---如果沒有線程等待在條件變量cond上面,那麼這個兩個函數將沒有任何作用


  ///---關於線程專有數據鍵246)、int pthread_key_create(pthread_key_t * key,void(*destrcutor)(void*)) //函數返回在key裏面
  ///---創建鍵的作用只是爲每一個線程相連一個指向其專有存儲空間的指針,這些指針的初始值都是null,key一旦
  ///---創建成功,那麼就可以通過函數pthread_getspecific()使之指向各自分配的專有數據存儲空間
  ///---第二個參數是一個析構函數,這個函數負責在線程終止時做一些回收工作,所以當線程終止時,線程會查看
  ///---線程專有數據鍵,如果上面有安裝析構函數的話,那麼就執行這個析構函數
  ///---需要注意的是,線程專有數據鍵只能由一個線程創建一次,如果多次創建,會丟失數據
  ///---下面這個函數可以保證一個專有數據鍵只創建一次247)、pthread_once_t once_control=PTHREAD_ONCE_INIT;
  (248)、int pthread_once(pthread_once_t* once_control,void(*init_routine)(void))
  ///---第二個參數是一個初始化參數,pthread_once函數會記錄這個初始化函數是否已經被調用,如果已經被調用
  ///---那麼任何調用pthread_once函數創建的數據key都將以失敗返回
  ///---下面的函數可以用來刪除一個專有數據鍵249)、int pthread_key_delete(pthread_key_t key)

  ///---對於每一個線程,當線程專有數據鍵創建時,都是null的,爲了使用線程專有數據鍵,每一個線程需要給專有數據鍵指定值
  ///---線程專有數據鍵是全局的,線程內的所有函數都能訪問,但是每一個線程與鍵相連的存儲空間是獨立的,因此,他們是私有的
  ///---也就是,他們是對線程私有的全局數據
  ///---下面的函數用來設置線程的專有數據和訪問線程專有數據250)、int pthread_setspecific(pthread_key_t key,const void* value) //設置value爲調用線程的線程專有數據鍵key251)、void *pthread_getspecific(pthread_key_t key)//獲得鍵key對應於調用線程的專有數據

  ///---線程與信號
  ///---在多線程的情況下,信號屏蔽不再是整個進程只有一個,而是每個線程一個
  ///---雖然所以線程共享相同的信號動作,但是每個線程可以阻塞自己不想處理的信號
  ///---下面的函數用來設置信號屏蔽252)、int pthread_sigmask(int how,const sigset_t* set,sigset_t* oldset)
  ///---how->
  ///---SIG_BLOCK:將set添加進來
  ///---SIG_UNBLOCK:將set移除
  ///---SIG_SETMASK:替換原來的

  ///---下面的函數用來向線程發送信號
  ///---線程向進程發送信號任然使用kill253)、int pthread_kill(pthread_t thread,int aigno)
  ///---線程可以用下面的方式向自己發送信號
  pthread_kill(pthread_self(),sig)  or   raise(sig)

  ///---等待信號,在接收到信號之後直接對信號進行處理,而不需要信號句柄
  ///---該函數將阻塞調用線程直到出現set裏面的信號,sig會返回信號數量254)、int sigwait(const sigset_t* set,int * sig)

  ///---要注意的是,在線程調用sigwait之前,所有線程都應當阻塞了信號集set中的信號,否則會導致不可預測的結果


  /*--2016/4/16--hujian--*/















































發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章