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\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

    } 

}
复制代码

 

运行结果:
Linux下的C编程

 

进程的创建

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

        } 

    } 

}
复制代码

 

 

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\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); 

}
复制代码

 

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\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); 

} 
复制代码

 

5、信号

Linux下的C编程

#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); 

}
复制代码

 

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\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); 

    } 

}
复制代码

 

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\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); 

} 
复制代码

 

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?\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

你可能感兴趣的:(linux)