Linux下的C編程

一、程序的編譯、運行
二、進程
三、文件
四、時間
五、信號
六、消息
七、線程
八、網絡html

一、程序的編譯、運行c++

簡單的編譯:gcc test.cshell

運行:./a.out編程


二、進程服務器

複製代碼
#include <unistd.h>
#include <pwd.h>
#include <sys/types.h>
#include <stdio.h>
int main(int argc,char **argv) 
{ 
    pid_t my_pid,parent_pid; //進程id,進程的父進程id
    uid_t my_uid,my_euid;  //用戶id,有效用戶id
    gid_t my_gid,my_egid;  //組id,有效組id
    struct passwd *my_info;

    my_pid=getpid(); 
    parent_pid=getppid(); 
    my_uid=getuid(); 
    my_euid=geteuid(); 
    my_gid=getgid(); 
    my_egid=getegid(); 
    my_info=getpwuid(my_uid);

    printf("Process ID:%ld\n",my_pid); 
    printf("Parent ID :%ld\n",parent_pid); 
    printf("User ID:%ld\n",my_uid); 
    printf("Effective User ID :%ld\n",my_euid); 
    printf("Group ID :%ld\n",my_gid); 
    printf("Effective Group ID :%ld\n",my_egid):

    if(my_info) 
    {
        printf("My Login Name:%s\n" ,my_info->pw_name); //登陸名稱
         printf("My Password:%s\n" ,my_info->pw_passwd); //登陸口令
         printf("My User ID:%ld\n",my_info->pw_uid); //用戶ID
        printf("My Group ID:%ld\n",my_info->pw_gid); //用戶組ID
        printf("My Real Name:%s\n" ,my_info->pw_gecos); //用戶的真名
         printf("My Home Dir:%s\n", my_info->pw_dir); //用戶的目錄
         printf("My Work Shell:%s\n", my_info->pw_shell); //用戶的SHELL
    } 
}
複製代碼

 

運行結果:
網絡

 

進程的建立socket

建立進程
#include <unistd.h>
pid_t fork();函數

阻塞進程
#include <sys/types.h>;
#include <sys/wait.h>;
pid_t wait(int *stat_loc);
pid_t waitpid(pid_t pid,int *stat_loc,int options);post

新進程執行一個程序
#include <unistd.h>;
int execl(const char *path,const char *arg,...);
int execlp(const char *file,const char *arg,...);
int execle(const char *path,const char *arg,...);
int execv(const char *path,char *const argv[]);
int execvp(const char *file,char *const argv[]);ui

複製代碼
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <errno.h>
#include <math.h>
void main(void) 
{ 
    pid_t child; 
    int status; 
    printf("This will demostrate how to get child status\n"); 
    if((child=fork()) == -1) 
    { 
        printf("Fork Error:%s\n",strerror(errno)); 
        exit(1); 
    } 
    else if(child == 0) 
    { 
        int i; 
        printf("I am the child:%ld\n",getpid()); 
        for(i=0;i<1000000;i++) 
            sin(i); 
        i=5; 
        printf("I exit with %d\n",i); 
        exit(i); 
    } 
    while(((child=wait(&status)) == -1)&(errno == EINTR)); 
    if(child == -1) 
        printf("Wait Error:%s\n",strerror(errno)); 
    else if(!status) 
        printf("Child %ld terminated normally return status is zero\n", child); 
    else if(WIFEXITED(status)) 
        printf("Child %ld terminated normally return status is %d\n", child,WEXITSTATUS(status)); 
    else if(WIFSIGNALED(status))
        printf("Child %ld terminated due to signal %d znot caught\n", child,WTERMSIG(status));  
}
複製代碼

 

後臺進程

父進程建立一個子進程,子進程殺死父進程,信號處理全部的工做由子進程處理

複製代碼
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <signal.h>

#define MAIL "/var/spool/mail/hoyt"  /* Linux  的默任我的的郵箱地址是 /var/spool/mail/用戶的登陸名 */
#define SLEEP_TIME 10 /* 睡眠 10 秒鐘 */

main(void) 
{ 
    pid_t child; 
    if((child=fork())==-1) 
    { 
        printf("Fork Error:%s\n",strerror(errno)); 
        exit(1); 
    } 
    else if(child>0) 
    while(1); 
    if(kill(getppid(),SIGTERM)==-1) 
    { 
        printf("Kill Parent Error:%s\n",strerror(errno)); 
        exit(1);
    }
    { 
        int mailfd; 
        while(1) 
        { 
            if((mailfd=open(MAIL,O_RDONLY))!=-1) 
            { 
                fprintf(stderr,"%s","\007"); 
                close(mailfd); 
            }  
            sleep(SLEEP_TIME); 
        } 
    } 
}
複製代碼

 

 

三、文件

 

文件的建立和讀寫

複製代碼
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <string.h>

#define BUFFER_SIZE 1024 
int main(int argc,char **argv) 
{ 
    int from_fd,to_fd; 
    int bytes_read,bytes_write; 
    char buffer[BUFFER_SIZE]; 
    char *ptr; 
    if(argc!=3) 
    { 
        fprintf(stderr,"Usage:%s fromfile tofile\n\a",argv[0]); 
        exit(1); 
    }
    /* 打開源文件 */ 
    if((from_fd=open(argv[1],O_RDONLY))==-1) 
    { 
        fprintf(stderr,"Open %s Error :%s\n",argv[1],strerror(errno)); 
        exit(1); 
    } 
    /* 建立目的文件 */ 
    if((to_fd=open(argv[2],O_WRONLY|O _CREAT,S_IRUSR|S_IWUSR))==-1) 
    { 
        fprintf(stderr,"Open %s Error :%s\n",argv[2],strerror(errno)); 
        exit(1); 
    } 
    /* 如下代碼是一個經典的拷貝文件的代碼 */ 
    while(bytes_read=read(from_fd,buffer,BUFFER_SIZE)) 
    { 
        /* 一個致命的錯誤發生了 */ 
        if((bytes_read==-1)&&(errno!=EINTR)) break; 
        else if(bytes_read>;0) 
        { 
            ptr=buffer; 
            while(bytes_write=write(to_fd,ptr,bytes_read)) 
            { 
                /* 一個致命錯誤發生了 */ 
                if((bytes_write==-1)&&(errno!=EINTR))break; 
                /* 寫完了全部讀的字節 */ 
                else if(bytes_write==bytes_read) break; 
                /* 只寫了一部分,繼續寫 */ 
                else if(bytes_write>;0) 
                { 
                    ptr+=bytes_write; 
                    bytes_read-=bytes_write; 
                } 
            } 
            /* 寫的時候發生的致命錯誤 */ 
            if(bytes_write==-1)break; 
        } 
    } 
    close(from_fd); 
    close(to_fd); 
    exit(0); 
}
複製代碼

 

文件的屬性

複製代碼
#include <unistd.h>int access(const char *pathname,int mode); 

#include <sys/stat.h> 
#include <unistd.h>int stat(const char *file_name,struct stat *buf); 
int fstat(int filedes,struct stat *buf); 
struct stat { 
    dev_t st_dev; /*  設備 */ 
    ino_t st_ino; /*  節點 */  
    mode_t st_mode; /* 模式 */ 
    nlink_t st_nlink; /*  硬鏈接 */ 
    uid_t st_uid; /*  用戶ID */ 
    gid_t st_gid; /*  組ID */ 
    dev_t st_rdev; /*  設備類型 */ 
    off_t st_off; /* 文件字節數 */ 
    unsigned long st_blksize; /* 塊大小 */ 
    unsigned long st_blocks; /*  塊數 */ 
    time_t st_atime; /*  最後一次訪問時間 */ 
    time_t st_mtime; /* 最後一次修改時間 */ 
    time_t st_ctime; /*  最後一次改變時間(指屬性) */ 
};
複製代碼

 

目錄文件

頭文件及庫函數

複製代碼
#include <unistd.h>
char *getcwd(char *buffer,size_t size);

#include <dirent.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
int mkdir(const char *path,mode_t mode); 
DIR *opendir(const char *path); 
struct dirent *readdir(DIR *dir); 
void rewinddir(DIR *dir); 
off_t telldir(DIR *dir); 
void seekdir(DIR *dir,off_t off); 
int closedir(DIR *dir); 
struct dirent { 
long d_ino; 
off_t d_off; 
unsigned short d_reclen; 
char d_name[NAME_MAX+1]; /*  文件名稱 */
複製代碼
複製代碼
//舉例
#include <unistd.h> #include <stdio.h> #include <errno.h> #include <sys/types.h> #include <sys/stat.h> #include <dirent.h> #include <time.h> static int get_file_size_time(const char *filename) { struct stat statbuf; if(stat(filename,&statbuf)==-1) { printf("Get stat on %s Error:%s\n", filename,strerror(errno)); return(-1); } if(S_ISDIR(statbuf.st_mode)) return(1); if(S_ISREG(statbuf.st_mode)) printf("%s size :%ld bytes\tmodified at %s", filename,statbuf.st_size,ctime(&statbuf.st_mtime)); return(0); } int main(int argc,char **argv) { DIR *dirp; struct dirent *direntp; int stats; if(argc!=2) { printf("Usage:%s filename\n\a",argv[0]); exit(1); } if(((stats=get_file_size_time(argv[1]))==0)||(stats==-1))exit(1); if((dirp=opendir(argv[1]))==NULL) { printf("Open Directory %s Error :%s\n", argv[1],strerror(errno)); exit(1); } while((direntp=readdir(dirp))!=NULL) if(get_file_size_time(direntp-<d_name)==-1)break; closedir(dirp); exit(1); }
複製代碼

 

管道文件

管道pipe

複製代碼
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/wait.h>

#define BUFFER 255 

int main(int argc,char **argv) 
{ 
    char buffer[BUFFER+1]; 
    int fd[2]; 
    if(argc!=2) 
    { 
        fprintf(stderr,"Usage:%s string\n\a",argv[0]); 
        exit(1); 
    } 
    if(pipe(fd)!=0) 
    { 
        fprintf(stderr,"Pipe Error :%s\n\a",strerror(errno)); 
        exit(1); 
    } 
    if(fork()==0) 
    { 
        close(fd[0]); 
        printf("Child[%d] Write to pipe\n\a",getpid()); 
        snprintf(buffer,BUFFER,"%s",argv[1]); 
        write(fd[1],buffer,strlen(buffer)); 
        printf("Child[%d] Quit\n\a",getpid()); 
        exit(0); 
    } 
    else 
    { 
        close(fd[1]); 
        printf("Parent[%d] Read from pipe\n\a",getpid());
        memset(buffer,'\0',BUFFER+1); 
        read(fd[0],buffer,BUFFER); 
        printf("Parent[%d] Read:%s\n",getpid(),buffer); 
        exit(1); 
    } 
}
複製代碼

重定向dup2

複製代碼
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>

#define BUFFER_SIZE 1024 

int main(int argc,char **argv) 
{ 
    int fd; 
    char buffer[BUFFER_SIZE]; 
    if(argc!=2) 
    { 
        fprintf(stderr,"Usage:%s outfilename\n\a",argv[0]); 
        exit(1); 
    } 
    if((fd=open(argv[1],O_WRONLY|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR))==-1) 
    { 
        fprintf(stderr,"Open %s Error :%s\n\a",argv[1],strerror(errno)); 
        exit(1); 
    } 
    if(dup2(fd,STDOUT_FILENO)==-1) 
    { 
        fprintf(stderr,"Redirect Standard Out Error :%s\n\a",strerror(errno)); 
        exit(1); 
    } 
    fprintf(stderr,"Now,please input string"); 
    fprintf(stderr,"(To quit use CTRL+D)\n"); 
    while(1)
    { 
        fgets(buffer,BUFFER_SIZE,stdin); 
        if(feof(stdin))break; 
        write(STDOUT_FILENO,buffer,strlen(buffer)); 
    } 
    exit(0); 
}
複製代碼

 

四、時間

 

時間的表示

#include <time.h> 
time_t time(time_t *tloc); 
char *ctime(const time_t *clock); 

時間的測量

複製代碼
#include <sys/time.h> 
#include <stdio.h>
#include <math.h>

void function() 
{ 
    unsigned int i,j; 
    double y; 
    for(i=0;i<1000;i++) 
        for(j=0;j<1000;j++) 
            y=sin((double)i); 
} 

main()
{ 
    struct timeval tpstart,tpend; 
    float timeuse; 
    gettimeofday(&tpstart,NULL); 
    function(); 
    gettimeofday(&tpend,NULL); 
    timeuse=1000000*(tpend.tv_sec-tpstart.tv_sec)+ 
    tpend.tv_usec-tpstart.tv_usec; 
    timeuse/=1000000; 
    printf("Used Time:%f\n",timeuse); 
    exit(0); 
}
複製代碼

計時器

複製代碼
#include <sys/time.h>
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>

#define PROMPT " 時間已通過去了兩秒鐘\n\a"

char *prompt=PROMPT; 
unsigned int len; 

void prompt_info(int signo) 
{ 
    write(STDERR_FILENO,prompt,len); 
} 

void init_sigaction(void) 
{ 
    struct sigaction act; 
    act.sa_handler=prompt_info; 
    act.sa_flags=0; 
    sigemptyset(&act.sa_mask); 
    sigaction(SIGPROF,&act,NULL); 
}
 
void init_time() 
{ 
    struct itimerval value; 
    value.it_value.tv_sec=2; 
    value.it_value.tv_usec=0; 
    value.it_interval=value.it_value; 
    setitimer(ITIMER_PROF,&value,NULL); 
} 

int main() 
{ 
    len=strlen(prompt); 
    init_sigaction(); 
    init_time(); 
    while(1); 
    exit(0); 
} 
複製代碼

 

五、信號

#include <sys/types.h>
#include <signal.h>
#include <unistd.h>

int kill(pid_t pid,int sig);
kill系統調用負責向進程發送信號sig.
若是pid是正數,那麼向信號sig被髮送到進程pid.
若是pid等於 0, 那麼信號sig被髮送到因此和pid進程在同一個進程組的進程
若是pid等於-1,那麼信號發給全部的進程表中的進程,除了最大的哪一個進程號.
若是pid因爲-1,和0 同樣,只是發送進程組是-pid

int raise(int sig);
raise 系統調用向本身發送一個sig信號

unisigned int alarm(unsigned int seconds);
alarm 函數能夠在seconds秒後向本身發送一個SIGALRM 信號

複製代碼
//經常使用的信號屏蔽函數
#include <signal.h>
int sigemptyset(sigset_t *set); 
int sigfillset(sigset_t *set); 
int sigaddset(sigset_t *set,int signo); 
int sigdelset(sigset_t *set,int signo); 
int sigismember(sigset_t *set,int signo); 
int sigprocmask(int how,const sigset_t *set,sigset_t *oset); 
複製代碼
複製代碼
#include <signal.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>

int main(int argc,char **argv) 
{ 
    double y; 
    sigset_t intmask; 
    int i,repeat_factor; 
    if(argc!=2) 
    { 
        fprintf(stderr,"Usage:%s repeat_factor\n\a",argv[0]); 
        exit(1); 
    } 
    if((repeat_factor=atoi(argv[1]))<1)repeat_factor=10; 
    sigemptyset(&intmask); /*  將信號集合設置爲空 */
    sigaddset(&intmask,SIGINT); /* 加入中斷 Ctrl+C  信號*/ 
    while(1) 
    { 
        /* 阻塞信號,咱們不但願保存原來的集合因此參數爲NULL*/ 
        sigprocmask(SIG_BLOCK,&intmask,NULL); 
        fprintf(stderr,"SIGINT signal blocked\n"); 
        for(i=0;i<repeat_factor;i++)
            y=sin((double)i); 
        fprintf(stderr,"Blocked calculation is finished\n"); 
        /* 取消阻塞 */ 
        sigprocmask(SIG_UNBLOCK,&intmask,NULL); 
        fprintf(stderr,"SIGINT signal unblocked\n"); 
        for(i=0;i<repeat_factor;i++)
            y=sin((double)i); 
        fprintf(stderr,"Unblocked calculation is finished\n"); 
    } 
    exit(0); 
}
複製代碼

sigaction 函數

複製代碼
#include <signal.h>; 
 
int sigaction(int signo,const struct sigaction *act,struct sigaction *oact); 
struct sigaction { 
    (*sa_handler)(int signo); 
    void (*sa_sigaction)(int siginfo_t *info,void *act); 
    sigset_t sa_mask; 
    int sa_flags; 
    void (*sa_restore)(void); 
}
複製代碼
複製代碼
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>

#define PROMPT " 你想終止程序嗎?" 
char *prompt=PROMPT; 

void ctrl_c_op(int signo) 
{ 
    write(STDERR_FILENO,prompt,strlen(prompt)); 
} 

int main() 
{ 
    struct sigaction act; 
    act.sa_handler=ctrl_c_op; 
    sigemptyset(&act.sa_mask); 
    act.sa_flags=0; 
    if(sigaction(SIGINT,&act,NULL)<0) 
    { 
        fprintf(stderr,"Install Signal Action Error :%s\n\a",strerror(errno)); 
        exit(1); 
    } 
    while(1); 
}
複製代碼

 其餘信號函數

複製代碼
#include <unistd.h>
#include <signal.h>
int pause(void); 
int sigsuspend(const sigset_t *sigmask); 

#include <sigsetjmp>
int sigsetjmp(sigjmp_buf  env,int val); 
void siglongjmp(sigjmp_buf  env,int val);
複製代碼

實例

複製代碼
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <string.h>
#include <pwd.h>
#include <sys/types.h>
#include <sys/stat.h>

/* Linux  的默任我的的郵箱地址是 /var/spool/mail/ */ 
#define MAIL_DIR "/var/spool/mail/" 
/* 睡眠 10 秒鐘 */ 
#define SLEEP_TIME 10 
#define MAX_FILENAME 255 
unsigned char notifyflag=1; 

long get_file_size(const char *filename) 
{ 
    struct stat buf; 
    if(stat(filename,&;buf)==-1) 
    { 
        if(errno==ENOENT) return 0; 
        else return -1; 
    } 
    return (long)buf.st_size;
}
 
void send_mail_notify(void) 
{ 
    fprintf(stderr,"New mail has arrived\007\n"); 
} 

void turn_on_notify(int signo) 
{ 
    notifyflag=1; 
} 

void turn_off_notify(int signo) 
{ 
    notifyflag=0; 
} 

int check_mail(const char *filename) 
{ 
    long old_mail_size,new_mail_size; 
    sigset_t blockset,emptyset; 
    sigemptyset(&;blockset); 
    sigemptyset(&;emptyset); 
    sigaddset(&;blockset,SIGUSR1); 
    sigaddset(&;blockset,SIGUSR2); 
    old_mail_size=get_file_size(filename); 
    if(old_mail_size<0)return 1; 
    if(old_mail_size>0) send_mail_notify(); 
    sleep(SLEEP_TIME); 
    while(1) 
    { 
        if(sigprocmask(SIG_BLOCK,&;blockset,NULL)<0) return 1; 
        while(notifyflag==0)
            sigsuspend(&;emptyset); 
        if(sigprocmask(SIG_SETMASK,&;emptyset,NULL)<0) return 1; 
        new_mail_size=get_file_size(filename); 
        if(new_mail_size>old_ma il_size) send_mail_notify(); 
        old_mail_size=new_mail_size; 
        sleep(SLEEP_TIME); 
    } 
} 

int main(void) 
{ 
    char mailfile[MAX_FILENAME]; 
    struct sigaction newact; 
    struct passwd *pw; 
    if((pw=getpwuid(getuid()))==NULL) 
    { 
        fprintf(stderr,"Get Login Name Error :%s\n\a",strerror(errno)); 
        exit(1); 
    } 
    strcpy(mailfile,MAIL_DIR); 
    strcat(mailfile,pw->pw_name); 
    newact.sa_handler=turn_on_notify; 
    newact.sa_flags=0; 
    sigemptyset(&;newact.sa_mask); 
    sigaddset(&;newact.sa_mask,SIGUSR1); 
    sigaddset(&;newact.sa_mask,SIGUSR2); 
    if(sigaction(SIGUSR1,&;newact,NULL)<0) 
        fprintf(stderr,"Turn On Error :%s\n\a",strerror(errno)); 
    newact.sa_handler=turn_off_notify; 
    if(sigaction(SIGUSR1,&;newact,NULL)<0) 
        fprintf(stderr,"Turn Off  Error :%s\n\a",strerror(errno)); 
    check_mail(mailfile); 
    exit(0); 
}
複製代碼

 

六、消息

POSIX 無名信號量函數:
#include <semaphore.h>
int sem_init(sem_t *sem,int pshared,unsigned int value);
int sem_destroy(sem_t *sem);
int sem_wait(sem_t *sem);
int sem_trywait(sem_t *sem);
int sem_post(sem_t *sem);
int sem_getvalue(sem_t *sem);

 

System V信號量

信號量的主要用途是保護臨界資源(在一個時刻只被一個進程所擁有)

複製代碼
#include <stdio.h> 
#include <unistd.h> 
#include <limits.h> 
#include <errno.h> 
#include <string.h> 
#include <stdlib.h> 
#include <sys/stat.h> 
#include <sys/wait.h> 
#include <sys/ipc.h> 
#include <sys/sem.h> 

#define PERMS S_IRUSR|S_IWUSR 

void init_semaphore_struct(struct sembuf  *sem,int semnum, int semop,int semflg) 
{ 
    /* 初始話信號量結構 */
    sem->sem_num=semnum; 
    sem->sem_op=semop; 
    sem->sem_flg=semflg; 
} 

int del_semaphore(int semid) 
{ 
    /* 信號量並不隨程序的結束而被刪除,若是咱們沒刪除的話(將1 改成0) 能夠用ipcs 命令查看到信號量,用ipcrm 能夠刪除信號量的 */ 
    #if  1 
        return semctl(semid,0,IPC_RMID); 
    #endif 
}
 
int main(int argc,char **argv) 
{ 
    char buffer[MAX_CANON],*c; 
    int i,n; 
    int semid,semop_ret,status; 
    pid_t childpid; 
    struct sembuf  semwait,semsignal; 
    if((argc!=2)||((n=atoi(argv[1]))<1)) 
    { 
        fprintf(stderr,"Usage:%s number\n\a",argv[0]); 
        exit(1); 
    } 
    /* 使用 IPC_PRIVATE  表示由系統選擇一個關鍵字來建立 */ 
    /* 建立之後信號量的初始值爲 0 */ 
    if((semid=semget(IPC_PRIVATE,1,PERMS))==-1) 
    { 
        fprintf(stderr,"[%d] :Acess Semaphore Error:%s\n\a",getpid(),strerror(errno)); 
        exit(1); 
    } 
    /* semwait 是要求資源的操做(-1) */ 
    init_semaphore_struct(&semwait,0,-1,0); 
    /* semsignal 是釋放資源的操做(+1) */ 
    init_semaphore_struct(&semsignal,0,1,0); 
    /* 開始的時候有一個系統資源(一個標準錯誤輸出) */ 
    if(semop(semid,&semsignal,1)==-1) 
    { 
        fprintf(stderr,"[%d] :Increment Semaphore Error:%s\n\a",getpid(),strerror(errno)); 
        if(del_semaphore(semid)==-1) 
        fprintf(stderr,"[%d] :Destroy Semaphore Error:%s\n\a",getpid(),strerror(errno)); 
        exit(1); 
    } 
    /* 建立一個進程鏈 */ 
    for(i=0;i<n;i++) 
        if(childpid=fork()) break; 
    sprintf(buffer,"[i=%d]-->[Process=%d]-->[Parent=%d]-->[Child=%d]\n",i,getpid(),getppid(),childpid); 
    c=buffer; 
    /* 這裏要求資源,進入原子操做 */ 
    while(((semop_ret=semop(semid,&semwait,1))==-1)&&(errno==EINTR)); 
    if(semop_ret==-1) 
    { 
        fprintf(stderr,"[%d] :Decrement Semaphore Error:%s\n\a", getpid(),strerror(errno)); 
    } 
    else 
    { 
        while(*c!='\0')fputc(*c++,stderr); 
        /* 原子操做完成,趕快釋放資源 */ 
        while(((semop_ret=semop(semid,&semsignal,1))==-1)&&(errno==EINTR)); 
        if(semop_ret==-1) 
            fprintf(stderr,"[%d] :Increment Semaphore Error:%s\n\a",getpid(),strerror(errno)); 
    } 
    /* 不可以在其餘進程反問信號量的時候,咱們刪除了信號量 */ 
    while((wait(&status)==-1)&&(errno==EINTR)); 
    /* 信號量只可以被刪除一次的 */ 
    if(i==1) 
        if(del_semaphore(semid)==-1) 
            fprintf(stderr,"[%d] :Destroy Semaphore Error:%s\n\a", getpid(),strerror(errno)); 
    exit(0); 
}
複製代碼

 

System V消息隊列

複製代碼
//服務端 server.c 
#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 
#include <errno.h> 
#include <unistd.h> 
#include <sys/types.h> 
#include <sys/ipc.h> 
#include <sys/stat.h> 
#include <sys/msg.h> 

#define MSG_FILE "server.c" 
#define BUFFER 255 
#define PERM S_IRUSR|S_IWUSR 

struct msgtype { 
    long mtype; 
    char buffer[BUFFER+1]; 
}; 

int main() 
{ 
    struct msgtype msg; 
    key_t key; 
    int msgid;
    if((key=ftok(MSG_FILE,'a'))==-1) 
    { 
        fprintf(stderr,"Creat Key Error:%s\a\n",strerror(errno)); 
        exit(1); 
    } 
    if((msgid=msgget(key,PERM|IPC_CREAT|IPC_EXCL))==-1) 
    { 
        fprintf(stderr,"Creat Message Error :%s\a\n",strerror(errno)); 
        exit(1); 
    } 
    while(1) 
    { 
        msgrcv(msgid,&msg,sizeof(struct msgtype),1,0); 
        fprintf(stderr,"Server Receive :%s\n",msg.buffer); 
        msg.mtype=2; 
        msgsnd(msgid,&msg,sizeof(struct msgtype),0); 
    } 
    exit(0); 
}  


//客戶端(client.c) 
#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 
#include <errno.h> 
#include <sys/types.h> 
#include <sys/ipc.h> 
#include <sys/msg.h> 
#include <sys/stat.h> 

#define MSG_FILE "server.c" 
#define BUFFER 255 
#define PERM S_IRUSR|S_IWUSR 

struct msgtype { 
    long mtype; 
    char buffer[BUFFER+1]; 
};
 
int main(int argc,char **argv) 
{ 
    struct msgtype msg; 
    key_t key; 
    int msgid; 
    if(argc!=2) 
    { 
        fprintf(stderr,"Usage:%s string\n\a",argv[0]); 
        exit(1); 
    } 
    if((key=ftok(MSG_FILE,'a'))==-1) 
    { 
        fprintf(stderr,"Creat Key Error:%s\a\n",strerror(errno)); 
        exit(1); 
    } 
    if((msgid=msgget(key,PERM))==-1) 
    { 
        fprintf(stderr,"Creat Message Error :%s\a\n",strerror(errno)); 
        exit(1); 
    } 
    msg.mtype=1; 
    strncpy(msg.buffer,argv[1],BUFFER); 
    msgsnd(msgid,&msg,sizeof(struct msgtype),0); 
    memset(&msg,'\0',sizeof(struct msgtype)); 
    msgrcv(msgid,&msg,sizeof(struct msgtype),2,0); 
    fprintf(stderr,"Client receive :%s\n",msg.buffer); 
    exit(0); 
}
複製代碼

 System V共享內存

實現共享內存的幾個函數:
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
int shmget(key_t key,int size,int shmflg);
void *shmat(int shmid,const void *shmaddr,int shmflg);
int shmdt(const void *shmaddr);
int shmctl(int shmid,int cm d,struct shmid_ds *buf);

複製代碼
#include <stdio.h> 
#include <string.h> 
#include <errno.h>
#include <unistd.h> 
#include <sys/stat.h> 
#include <sys/types.h> 
#include <sys/ipc.h> 
#include <sys/shm.h> 

#define PERM S_IRUSR|S_IWUSR 

int main(int argc,char **argv) 
{ 
    int shmid; 
    char *p_addr,*c_addr; 
    if(argc!=2) 
    { 
        fprintf(stderr,"Usage:%s\n\a",argv[0]); 
        exit(1); 
    } 
    if((shmid=shmget(IPC_PRIVATE,1024,PERM))==-1) 
    { 
        fprintf(stderr,"Create Share Memory Error :%s\n\a",strerror(errno)); 
        exit(1); 
    } 
    if(fork()) 
    { 
        p_addr=shmat(shmid,0,0); 
        memset(p_addr,'\0',1024); 
        strncpy(p_addr,argv[1],1024); 
        exit(0); 
    } 
    else 
    { 
        c_addr=shmat(shmid,0,0); 
        printf("Client get %s",c_addr); 
        exit(0); 
    } 
}
複製代碼

 

七、線程

線程相關處理函數:
#include <pthread.h>
int pthread_create(pthread_t *thread,pthread_attr_t *attr, void *(*start_routine)(void *),void *arg);
void pthread_exit(void *retval);
int pthread_join(pthread *thread,void **thread_return);

複製代碼
#include <stdio.h> 
#include <unistd.h> 
#include <stdlib.h> 
#include <string.h> 
#include <errno.h> 
#include <pthread.h> 
#include <dirent.h> 
#include <fcntl.h> 
#include <sys/types.h> 
#include <sys/stat.h> 
#include <sys/time.h> 

#define BUFFER 512 

struct copy_file { 
    int infile; 
    int outfile; 
}; 

void *copy(void *arg) 
{ 
    int infile,outfile; 
    int bytes_read,bytes_write,*bytes_copy_p; 
    char buffer[BUFFER],*buffer_p; 
    struct copy_file *file=(struct copy_file *)arg; 
    infile=file->infile; 
    outfile=file->outfile; 
    /* 由於線程退出時,全部的變量空間都要被釋放,因此咱們只好本身分配內存了 */
    if((bytes_copy_p=(int *)malloc(sizeof(int)))==NULL) 
        pthread_exit(NULL); 
    bytes_read=bytes_write=0; 
    *bytes_copy_p=0; 
    /* 還記得怎麼拷貝文件嗎 */ 
    while((bytes_read=read(infile,buffer,BUFFER))!=0) 
    { 
        if((bytes_read==-1)&&(errno!=EINTR))break; 
        else if(bytes_read>0) 
        { 
            buffer_p=buffer; 
            while((bytes_write=write(outfile,buffer_p,bytes_read))!=0) 
            { 
                if((bytes_write==-1)&&(errno!=EINTR))break; 
                else if(bytes_write==bytes_read)break; 
                else if(bytes_write>0) 
                { 
                    buffer_p+=bytes_write; 
                    bytes_read-=bytes_write; 
                } 
            } 
            if(bytes_write==-1)break; 
            *bytes_copy_p+=bytes_read; 
        } 
    }  
    close(infile); 
    close(outfile); 
    pthread_exit(bytes_copy_p); 
}
 
int main(int argc,char **argv) 
{ 
    pthread_t *thread; 
    struct copy_file *file; 
    int byte_copy,*byte_copy_p,num,i,j; 
    char filename[BUFFER]; 
    struct dirent **namelist; 
    struct stat filestat; 
    /* 獲得當前路徑下面全部的文件(包含目錄)的個數 */ 
    if((num=scandir(".",&namelist,0,alphasort))<0) 
    { 
        fprintf(stderr,"Get File Num Error :%s\n\a",strerror(errno)); 
        exit(1); 
    } 
    /* 給線程分配空間,其實沒有必要這麼多的 */ 
    if(((thread=(pthread_t *)malloc(sizeof(pthread_t)*num))==NULL)||((file=(struct copy_file *)malloc(sizeof(struct copy_file)*num))==NULL)) 
    { 
        fprintf(stderr,"Out Of  Memory!\n\a"); 
        exit(1); 
    }  
 
    for(i=0,j=0;i<num;i++) 
    { 
        memset(filename,'\0',BUFFER); 
        strcpy(filename,namelist->d_name); 
        if(stat(filename,&filestat)==-1) 
        { 
            fprintf(stderr,"Get File Information :%s\n\a",strerror(errno)); 
            exit(1); 
        } 
        /* 咱們忽略目錄 */ 
        if(!S_ISREG(filestat.st_mode))continue; 
        if((file[j].infile=open(filename,O_RDONLY))<0) 
        { 
            fprintf(stderr,"Open %s Error :%s\n\a",filename,strerror(errno)); 
            continue; 
        } 
        strcat(filename,".bak"); 
        if((file[j].outfile=open(filename,O_W RONLY|O_CREAT,S_IRUSR|S_IWUSR))<0) 
        { 
            fprintf(stderr,"Creat %s Error :%s\n\a",filename,strerror(errno)); 
            continue; 
        } 
        /* 建立線程,進行文件拷貝 */ 
        if(pthread_create(&thread[j],NULL,copy,(void *)&file[j])!=0) 
            fprintf(stderr,"Create Thread[%d] Error :%s\n\a",i,strerror(errno)); 
        j++; 
    }  
    byte_copy=0; 
    for(i=0;i<j;i++) 
    { 
        /* 等待線程結束 */ 
        if(pthread_join(thread,(void **)&byte_copy_p)!=0) 
        fprintf(stderr,"Thread[%d] Join Error :%s\n\a",i,strerror(errno)); 
        else
        { 
            if(bytes_copy_p==NULL)continue; 
            printf("Thread[%d] Copy %d bytes\n\a",i,*byte_copy_p); 
            byte_copy+=*byte_copy_p; 
            /* 釋放咱們在 copy 函數裏面建立的內存 */  
            free(byte_copy_p);  
        } 
    } 
    printf("Total Copy Bytes %d\n\a",byte_copy); 
    free(thread); 
    free(file); 
    exit(0); 
} 
複製代碼

 

八、網絡

複製代碼
/*******  服務器程序 (server.c) ************/ 
#include <stdlib.h> 
#include <stdio.h> 
#include <errno.h> 
#include <string.h> 
#include <netdb.h> 
#include <sys/types.h> 
#include <netinet/in.h> 
#include <sys/socket.h>
 
int main(int argc, char *argv[]) 
{ 
    int sockfd,new_fd; 
    struct sockaddr_in server_addr; 
    struct sockaddr_in client_addr; 
    int sin_size,portnumber; 
    char hello[]="Hello! Are You Fine?\n"; 
    if(argc!=2) 
    { 
        fprintf(stderr,"Usage:%s portnumber\a\n",argv[0]); 
        exit(1); 
    } 
    if((portnumber=atoi(argv[1]))<0) 
    { 
        fprintf(stderr,"Usage:%s portnumber\a\n",argv[0]); 
        exit(1); 
    } 
    /* 服務器端開始創建 socket 描述符 */ 
    if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1) 
    { 
        fprintf(stderr,"Socket error :%s\n\a",strerror(errno)); 
        exit(1); 
    } 
    /* 服務器端填充 sockaddr 結構 */ 
    bzero(&server_addr,sizeof(struct sockaddr_in)); 
    server_addr.sin_family=AF_INET; 
    server_addr.sin_addr.s_addr=htonl(INADDR_ANY); 
    server_addr.sin_port=htons(portnumber); 
    /* 捆綁 sockfd 描述符 */ 
    if(bind(sockfd,(struct sockaddr *)(& server_addr),sizeof(struct sockaddr))== -1) 
    { 
        fprintf(stderr,"Bind error :%s\n\a",strerror(errno)); 
        exit(1); 
    } 
    /* 監聽 sockfd 描述符 */ 
    if(listen(sockfd,5)==-1) 
    { 
        fprintf(stderr,"Listen error:%s\n\a",strerror(errno)); 
        exit(1); 
    } 
    while(1) 
    { 
        /* 服務器阻塞,直到客戶程序創建鏈接 */ 
        sin_size=sizeof(struct sockaddr_in); 
        if((new_fd=accept(sockfd,(struct so ckaddr *)(&client_addr),&sin_size))==-1) 
        { 
            fprintf(stderr,"Accept error :%s\n\a",strerror(errno)); 
            exit(1); 
        } 
        fprintf(stderr,"Server get connection from %s\n", inet_ntoa(client_addr.sin_addr)); 
        if(write(new_fd,hello,strlen(hello))==-1) 
        { 
            fprintf(stderr,"Write Error:%s\n",strerror(errno)); 
            exit(1); 
        } 
        /* 這個通信已經結束 */ 
        close(new_fd); 
        /* 循環下一個 */ 
    } 
    close(sockfd); 
    exit(0); 
} 


/*******  客戶端程序 client.c ************/ 
#include <stdlib.h> 
#include <stdio.h> 
#include <errno.h> 
#include <string.h> 
#include <netdb.h> 
#include <sys/types.h> 
#include <netinet/in.h> 
#include <sys/socket.h> 

int main(int argc, char *argv[]) 
{ 
    int sockfd; 
    char buffer[1024]; 
    struct sockaddr_in server_addr; 
    struct hostent *host; 
    int portnumber,nbytes; 
    if(argc!=3) 
    { 
        fprintf(stderr,"Usage:%s hostname portnumber\a\n",argv[0]); 
        exit(1); 
    } 
    if((host=gethostbyname(argv[1]))==NULL) 
    { 
        fprintf(stderr,"Gethostname error\n"); 
        exit(1); 
    } 
    if((portnumber=atoi(argv[2]))<0) 
    { 
        fprintf(stderr,"Usage:%s hostname portnumber\a\n",argv[0]); 
        exit(1); 
    } 
    /* 客戶程序開始創建 sockfd描述符 */ 
    if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1) 
    { 
        fprintf(stderr,"Socket Error :%s\a\n",strerror(errno)); 
        exit(1); 
    } 
    /* 客戶程序填充服務端的資料 */ 
    bzero(&server_addr,sizeof(server_addr)); 
    server_addr.sin_family=AF_INET; 
    server_addr.sin_port=htons(portnumber); 
    server_addr.sin_addr=*((struct in_addr *)host->h_addr); 
    /* 客戶程序發起鏈接請求 */ 
    if(connect(sockfd,(struct sockaddr *)(& server_addr),sizeof(struct sockaddr))==-1) 
    { 
        fprintf(stderr,"Connect Error :%s\a\n",strerror(errno)); 
        exit(1); 
    } 
    /* 鏈接成功了 */
    if((nbytes=read(sockfd,buffer,1024))==-1) 
    { 
        fprintf(stderr,"Read Error:%s\n",strerror(errno)); 
        exit(1); 
    } 
    buffer[nbytes]='\0'; 
    printf("I have received :%s\n",buffer); 
    /* 結束通信 */ 
    close(sockfd); 
    exit(0); 
} 
複製代碼

 

完整版請參考: Linux操做系統下C語言編程入門

 

來源:http://www.cnblogs.com/JCSU/articles/3102260.html#a8

相關文章
相關標籤/搜索