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
    } 
}
复制代码

 

运行结果:

 

进程的创建

创建进程
#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、信号

#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

posted on 2013-08-30 20:39  猿人谷  阅读(922)  评论(0编辑  收藏  举报