• Linux下的C编程


    1、程序的编译、运行
    2、进程
    3、文件
    4、时间
    5、信号
    6、消息
    7、线程
    8、网络

    1、程序的编译、运行

    简单的编译:gcc test.c

    运行:./a.out


    2、进程

    复制代码
    #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
    ",my_pid); 
        printf("Parent ID :%ld
    ",parent_pid); 
        printf("User ID:%ld
    ",my_uid); 
        printf("Effective User ID :%ld
    ",my_euid); 
        printf("Group ID :%ld
    ",my_gid); 
        printf("Effective Group ID :%ld
    ",my_egid):
    
        if(my_info) 
        {
            printf("My Login Name:%s
    " ,my_info->pw_name); //登录名称
             printf("My Password:%s
    " ,my_info->pw_passwd); //登录口令
             printf("My User ID:%ld
    ",my_info->pw_uid); //用户ID
            printf("My Group ID:%ld
    ",my_info->pw_gid); //用户组ID
            printf("My Real Name:%s
    " ,my_info->pw_gecos); //用户的真名
             printf("My Home Dir:%s
    ", my_info->pw_dir); //用户的目录
             printf("My Work Shell:%s
    ", my_info->pw_shell); //用户的SHELL
        } 
    }
    复制代码

    运行结果:

    进程的创建

    创建进程
    #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);

    新进程执行一个程序
    #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[]);

    复制代码
    #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
    "); 
        if((child=fork()) == -1) 
        { 
            printf("Fork Error:%s
    ",strerror(errno)); 
            exit(1); 
        } 
        else if(child == 0) 
        { 
            int i; 
            printf("I am the child:%ld
    ",getpid()); 
            for(i=0;i<1000000;i++) 
                sin(i); 
            i=5; 
            printf("I exit with %d
    ",i); 
            exit(i); 
        } 
        while(((child=wait(&status)) == -1)&(errno == EINTR)); 
        if(child == -1) 
            printf("Wait Error:%s
    ",strerror(errno)); 
        else if(!status) 
            printf("Child %ld terminated normally return status is zero
    ", child); 
        else if(WIFEXITED(status)) 
            printf("Child %ld terminated normally return status is %d
    ", child,WEXITSTATUS(status)); 
        else if(WIFSIGNALED(status))
            printf("Child %ld terminated due to signal %d znot caught
    ", 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
    ",strerror(errno)); 
            exit(1); 
        } 
        else if(child>0) 
        while(1); 
        if(kill(getppid(),SIGTERM)==-1) 
        { 
            printf("Kill Parent Error:%s
    ",strerror(errno)); 
            exit(1);
        }
        { 
            int mailfd; 
            while(1) 
            { 
                if((mailfd=open(MAIL,O_RDONLY))!=-1) 
                { 
                    fprintf(stderr,"%s","07"); 
                    close(mailfd); 
                }  
                sleep(SLEEP_TIME); 
            } 
        } 
    }
    复制代码

    3、文件

    文件的创建和读写

    复制代码
    #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
    a",argv[0]); 
            exit(1); 
        }
        /* 打开源文件 */ 
        if((from_fd=open(argv[1],O_RDONLY))==-1) 
        { 
            fprintf(stderr,"Open %s Error :%s
    ",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
    ",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 ", filename,strerror(errno)); return(-1); } if(S_ISDIR(statbuf.st_mode)) return(1); if(S_ISREG(statbuf.st_mode)) printf("%s size :%ld bytes modified 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 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 ", 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
    a",argv[0]); 
            exit(1); 
        } 
        if(pipe(fd)!=0) 
        { 
            fprintf(stderr,"Pipe Error :%s
    a",strerror(errno)); 
            exit(1); 
        } 
        if(fork()==0) 
        { 
            close(fd[0]); 
            printf("Child[%d] Write to pipe
    a",getpid()); 
            snprintf(buffer,BUFFER,"%s",argv[1]); 
            write(fd[1],buffer,strlen(buffer)); 
            printf("Child[%d] Quit
    a",getpid()); 
            exit(0); 
        } 
        else 
        { 
            close(fd[1]); 
            printf("Parent[%d] Read from pipe
    a",getpid());
            memset(buffer,'',BUFFER+1); 
            read(fd[0],buffer,BUFFER); 
            printf("Parent[%d] Read:%s
    ",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
    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
    a",argv[1],strerror(errno)); 
            exit(1); 
        } 
        if(dup2(fd,STDOUT_FILENO)==-1) 
        { 
            fprintf(stderr,"Redirect Standard Out Error :%s
    a",strerror(errno)); 
            exit(1); 
        } 
        fprintf(stderr,"Now,please input string"); 
        fprintf(stderr,"(To quit use CTRL+D)
    "); 
        while(1)
        { 
            fgets(buffer,BUFFER_SIZE,stdin); 
            if(feof(stdin))break; 
            write(STDOUT_FILENO,buffer,strlen(buffer)); 
        } 
        exit(0); 
    }
    复制代码

    4、时间

    时间的表示

    #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
    ",timeuse); 
        exit(0); 
    }
    复制代码

    计时器

    复制代码
    #include <sys/time.h>
    #include <stdio.h>
    #include <unistd.h>
    #include <signal.h>
    #include <string.h>
    
    #define PROMPT " 时间已经过去了两秒钟
    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); 
    } 
    复制代码

    5、信号

    #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
    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
    "); 
            for(i=0;i<repeat_factor;i++)
                y=sin((double)i); 
            fprintf(stderr,"Blocked calculation is finished
    "); 
            /* 取消阻塞 */ 
            sigprocmask(SIG_UNBLOCK,&intmask,NULL); 
            fprintf(stderr,"SIGINT signal unblocked
    "); 
            for(i=0;i<repeat_factor;i++)
                y=sin((double)i); 
            fprintf(stderr,"Unblocked calculation is finished
    "); 
        } 
        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
    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 arrived07
    "); 
    } 
    
    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
    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
    a",strerror(errno)); 
        newact.sa_handler=turn_off_notify; 
        if(sigaction(SIGUSR1,&;newact,NULL)<0) 
            fprintf(stderr,"Turn Off  Error :%s
    a",strerror(errno)); 
        check_mail(mailfile); 
        exit(0); 
    }
    复制代码

    6、消息

    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
    a",argv[0]); 
            exit(1); 
        } 
        /* 使用 IPC_PRIVATE  表示由系统选择一个关键字来创建 */ 
        /* 创建以后信号量的初始值为 0 */ 
        if((semid=semget(IPC_PRIVATE,1,PERMS))==-1) 
        { 
            fprintf(stderr,"[%d] :Acess Semaphore Error:%s
    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
    a",getpid(),strerror(errno)); 
            if(del_semaphore(semid)==-1) 
            fprintf(stderr,"[%d] :Destroy Semaphore Error:%s
    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]
    ",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
    a", getpid(),strerror(errno)); 
        } 
        else 
        { 
            while(*c!='')fputc(*c++,stderr); 
            /* 原子操作完成,赶快释放资源 */ 
            while(((semop_ret=semop(semid,&semsignal,1))==-1)&&(errno==EINTR)); 
            if(semop_ret==-1) 
                fprintf(stderr,"[%d] :Increment Semaphore Error:%s
    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
    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:%sa
    ",strerror(errno)); 
            exit(1); 
        } 
        if((msgid=msgget(key,PERM|IPC_CREAT|IPC_EXCL))==-1) 
        { 
            fprintf(stderr,"Creat Message Error :%sa
    ",strerror(errno)); 
            exit(1); 
        } 
        while(1) 
        { 
            msgrcv(msgid,&msg,sizeof(struct msgtype),1,0); 
            fprintf(stderr,"Server Receive :%s
    ",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
    a",argv[0]); 
            exit(1); 
        } 
        if((key=ftok(MSG_FILE,'a'))==-1) 
        { 
            fprintf(stderr,"Creat Key Error:%sa
    ",strerror(errno)); 
            exit(1); 
        } 
        if((msgid=msgget(key,PERM))==-1) 
        { 
            fprintf(stderr,"Creat Message Error :%sa
    ",strerror(errno)); 
            exit(1); 
        } 
        msg.mtype=1; 
        strncpy(msg.buffer,argv[1],BUFFER); 
        msgsnd(msgid,&msg,sizeof(struct msgtype),0); 
        memset(&msg,'',sizeof(struct msgtype)); 
        msgrcv(msgid,&msg,sizeof(struct msgtype),2,0); 
        fprintf(stderr,"Client receive :%s
    ",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
    a",argv[0]); 
            exit(1); 
        } 
        if((shmid=shmget(IPC_PRIVATE,1024,PERM))==-1) 
        { 
            fprintf(stderr,"Create Share Memory Error :%s
    a",strerror(errno)); 
            exit(1); 
        } 
        if(fork()) 
        { 
            p_addr=shmat(shmid,0,0); 
            memset(p_addr,'',1024); 
            strncpy(p_addr,argv[1],1024); 
            exit(0); 
        } 
        else 
        { 
            c_addr=shmat(shmid,0,0); 
            printf("Client get %s",c_addr); 
            exit(0); 
        } 
    }
    复制代码

    7、线程

    线程相关处理函数:
    #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
    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!
    a"); 
            exit(1); 
        }  
     
        for(i=0,j=0;i<num;i++) 
        { 
            memset(filename,'',BUFFER); 
            strcpy(filename,namelist->d_name); 
            if(stat(filename,&filestat)==-1) 
            { 
                fprintf(stderr,"Get File Information :%s
    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
    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
    a",filename,strerror(errno)); 
                continue; 
            } 
            /* 创建线程,进行文件拷贝 */ 
            if(pthread_create(&thread[j],NULL,copy,(void *)&file[j])!=0) 
                fprintf(stderr,"Create Thread[%d] Error :%s
    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
    a",i,strerror(errno)); 
            else
            { 
                if(bytes_copy_p==NULL)continue; 
                printf("Thread[%d] Copy %d bytes
    a",i,*byte_copy_p); 
                byte_copy+=*byte_copy_p; 
                /* 释放我们在 copy 函数里面创建的内存 */  
                free(byte_copy_p);  
            } 
        } 
        printf("Total Copy Bytes %d
    a",byte_copy); 
        free(thread); 
        free(file); 
        exit(0); 
    } 
    复制代码

    8、网络

    复制代码
    /*******  服务器程序 (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?
    "; 
        if(argc!=2) 
        { 
            fprintf(stderr,"Usage:%s portnumbera
    ",argv[0]); 
            exit(1); 
        } 
        if((portnumber=atoi(argv[1]))<0) 
        { 
            fprintf(stderr,"Usage:%s portnumbera
    ",argv[0]); 
            exit(1); 
        } 
        /* 服务器端开始建立 socket 描述符 */ 
        if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1) 
        { 
            fprintf(stderr,"Socket error :%s
    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
    a",strerror(errno)); 
            exit(1); 
        } 
        /* 监听 sockfd 描述符 */ 
        if(listen(sockfd,5)==-1) 
        { 
            fprintf(stderr,"Listen error:%s
    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
    a",strerror(errno)); 
                exit(1); 
            } 
            fprintf(stderr,"Server get connection from %s
    ", inet_ntoa(client_addr.sin_addr)); 
            if(write(new_fd,hello,strlen(hello))==-1) 
            { 
                fprintf(stderr,"Write Error:%s
    ",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 portnumbera
    ",argv[0]); 
            exit(1); 
        } 
        if((host=gethostbyname(argv[1]))==NULL) 
        { 
            fprintf(stderr,"Gethostname error
    "); 
            exit(1); 
        } 
        if((portnumber=atoi(argv[2]))<0) 
        { 
            fprintf(stderr,"Usage:%s hostname portnumbera
    ",argv[0]); 
            exit(1); 
        } 
        /* 客户程序开始建立 sockfd描述符 */ 
        if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1) 
        { 
            fprintf(stderr,"Socket Error :%sa
    ",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 :%sa
    ",strerror(errno)); 
            exit(1); 
        } 
        /* 连接成功了 */
        if((nbytes=read(sockfd,buffer,1024))==-1) 
        { 
            fprintf(stderr,"Read Error:%s
    ",strerror(errno)); 
            exit(1); 
        } 
        buffer[nbytes]=''; 
        printf("I have received :%s
    ",buffer); 
        /* 结束通讯 */ 
        close(sockfd); 
        exit(0); 
    } 
    复制代码

    完整版请参考: Linux操作系统下C语言编程入门

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

  • 相关阅读:
    数组
    2022杭电多校部分好题题解(更新至Day 10)
    js入门
    JS数据类型转换
    python赚钱小秘籍每日打新提醒
    jenkins+github+python执行测试用例
    python网络编程socket基础
    Dockerfile介绍与实操
    Docker部署jenkins详细过程
    Faker生成范围内的随机时间格式
  • 原文地址:https://www.cnblogs.com/heyonggang/p/3292460.html
Copyright © 2020-2023  润新知