一、程序的編譯、運行
二、進程
三、文件
四、時間
五、信號
六、消息
七、線程
八、網絡html
簡單的編譯:gcc test.cshell
運行:./a.out編程
#include <unistd.h> #include <pwd.h> #include <sys/types.h> #include <stdio.h> int main(int argc,char **argv) { pid_t my_pid,parent_pid; //進程id,進程的父進程id uid_t my_uid,my_euid; //用戶id,有效用戶id gid_t my_gid,my_egid; //組id,有效組id struct passwd *my_info; my_pid=getpid(); parent_pid=getppid(); my_uid=getuid(); my_euid=geteuid(); my_gid=getgid(); my_egid=getegid(); my_info=getpwuid(my_uid); printf("Process ID:%ld\n",my_pid); printf("Parent ID :%ld\n",parent_pid); printf("User ID:%ld\n",my_uid); printf("Effective User ID :%ld\n",my_euid); printf("Group ID :%ld\n",my_gid); printf("Effective Group ID :%ld\n",my_egid): if(my_info) { printf("My Login Name:%s\n" ,my_info->pw_name); //登陸名稱 printf("My Password:%s\n" ,my_info->pw_passwd); //登陸口令 printf("My User ID:%ld\n",my_info->pw_uid); //用戶ID printf("My Group ID:%ld\n",my_info->pw_gid); //用戶組ID printf("My Real Name:%s\n" ,my_info->pw_gecos); //用戶的真名 printf("My Home Dir:%s\n", my_info->pw_dir); //用戶的目錄 printf("My Work Shell:%s\n", my_info->pw_shell); //用戶的SHELL } }
運行結果:
網絡
進程的建立socket
建立進程
#include <unistd.h>
pid_t fork();函數
阻塞進程
#include <sys/types.h>;
#include <sys/wait.h>;
pid_t wait(int *stat_loc);
pid_t waitpid(pid_t pid,int *stat_loc,int options);post
新進程執行一個程序
#include <unistd.h>;
int execl(const char *path,const char *arg,...);
int execlp(const char *file,const char *arg,...);
int execle(const char *path,const char *arg,...);
int execv(const char *path,char *const argv[]);
int execvp(const char *file,char *const argv[]);ui
#include <unistd.h> #include <sys/types.h> #include <sys/wait.h> #include <stdio.h> #include <errno.h> #include <math.h> void main(void) { pid_t child; int status; printf("This will demostrate how to get child status\n"); if((child=fork()) == -1) { printf("Fork Error:%s\n",strerror(errno)); exit(1); } else if(child == 0) { int i; printf("I am the child:%ld\n",getpid()); for(i=0;i<1000000;i++) sin(i); i=5; printf("I exit with %d\n",i); exit(i); } while(((child=wait(&status)) == -1)&(errno == EINTR)); if(child == -1) printf("Wait Error:%s\n",strerror(errno)); else if(!status) printf("Child %ld terminated normally return status is zero\n", child); else if(WIFEXITED(status)) printf("Child %ld terminated normally return status is %d\n", child,WEXITSTATUS(status)); else if(WIFSIGNALED(status)) printf("Child %ld terminated due to signal %d znot caught\n", child,WTERMSIG(status)); }
後臺進程
父進程建立一個子進程,子進程殺死父進程,信號處理全部的工做由子進程處理
#include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <stdio.h> #include <errno.h> #include <fcntl.h> #include <signal.h> #define MAIL "/var/spool/mail/hoyt" /* Linux 的默任我的的郵箱地址是 /var/spool/mail/用戶的登陸名 */ #define SLEEP_TIME 10 /* 睡眠 10 秒鐘 */ main(void) { pid_t child; if((child=fork())==-1) { printf("Fork Error:%s\n",strerror(errno)); exit(1); } else if(child>0) while(1); if(kill(getppid(),SIGTERM)==-1) { printf("Kill Parent Error:%s\n",strerror(errno)); exit(1); } { int mailfd; while(1) { if((mailfd=open(MAIL,O_RDONLY))!=-1) { fprintf(stderr,"%s","\007"); close(mailfd); } sleep(SLEEP_TIME); } } }
文件的建立和讀寫
#include <unistd.h> #include <fcntl.h> #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <errno.h> #include <string.h> #define BUFFER_SIZE 1024 int main(int argc,char **argv) { int from_fd,to_fd; int bytes_read,bytes_write; char buffer[BUFFER_SIZE]; char *ptr; if(argc!=3) { fprintf(stderr,"Usage:%s fromfile tofile\n\a",argv[0]); exit(1); } /* 打開源文件 */ if((from_fd=open(argv[1],O_RDONLY))==-1) { fprintf(stderr,"Open %s Error :%s\n",argv[1],strerror(errno)); exit(1); } /* 建立目的文件 */ if((to_fd=open(argv[2],O_WRONLY|O _CREAT,S_IRUSR|S_IWUSR))==-1) { fprintf(stderr,"Open %s Error :%s\n",argv[2],strerror(errno)); exit(1); } /* 如下代碼是一個經典的拷貝文件的代碼 */ while(bytes_read=read(from_fd,buffer,BUFFER_SIZE)) { /* 一個致命的錯誤發生了 */ if((bytes_read==-1)&&(errno!=EINTR)) break; else if(bytes_read>;0) { ptr=buffer; while(bytes_write=write(to_fd,ptr,bytes_read)) { /* 一個致命錯誤發生了 */ if((bytes_write==-1)&&(errno!=EINTR))break; /* 寫完了全部讀的字節 */ else if(bytes_write==bytes_read) break; /* 只寫了一部分,繼續寫 */ else if(bytes_write>;0) { ptr+=bytes_write; bytes_read-=bytes_write; } } /* 寫的時候發生的致命錯誤 */ if(bytes_write==-1)break; } } close(from_fd); close(to_fd); exit(0); }
文件的屬性
#include <unistd.h>int access(const char *pathname,int mode); #include <sys/stat.h> #include <unistd.h>int stat(const char *file_name,struct stat *buf); int fstat(int filedes,struct stat *buf); struct stat { dev_t st_dev; /* 設備 */ ino_t st_ino; /* 節點 */ mode_t st_mode; /* 模式 */ nlink_t st_nlink; /* 硬鏈接 */ uid_t st_uid; /* 用戶ID */ gid_t st_gid; /* 組ID */ dev_t st_rdev; /* 設備類型 */ off_t st_off; /* 文件字節數 */ unsigned long st_blksize; /* 塊大小 */ unsigned long st_blocks; /* 塊數 */ time_t st_atime; /* 最後一次訪問時間 */ time_t st_mtime; /* 最後一次修改時間 */ time_t st_ctime; /* 最後一次改變時間(指屬性) */ };
目錄文件
頭文件及庫函數
#include <unistd.h> char *getcwd(char *buffer,size_t size); #include <dirent.h> #include <unistd.h> #include <fcntl.h> #include <sys/types.h> #include <sys/stat.h> int mkdir(const char *path,mode_t mode); DIR *opendir(const char *path); struct dirent *readdir(DIR *dir); void rewinddir(DIR *dir); off_t telldir(DIR *dir); void seekdir(DIR *dir,off_t off); int closedir(DIR *dir); struct dirent { long d_ino; off_t d_off; unsigned short d_reclen; char d_name[NAME_MAX+1]; /* 文件名稱 */
//舉例
#include <unistd.h> #include <stdio.h> #include <errno.h> #include <sys/types.h> #include <sys/stat.h> #include <dirent.h> #include <time.h> static int get_file_size_time(const char *filename) { struct stat statbuf; if(stat(filename,&statbuf)==-1) { printf("Get stat on %s Error:%s\n", filename,strerror(errno)); return(-1); } if(S_ISDIR(statbuf.st_mode)) return(1); if(S_ISREG(statbuf.st_mode)) printf("%s size :%ld bytes\tmodified at %s", filename,statbuf.st_size,ctime(&statbuf.st_mtime)); return(0); } int main(int argc,char **argv) { DIR *dirp; struct dirent *direntp; int stats; if(argc!=2) { printf("Usage:%s filename\n\a",argv[0]); exit(1); } if(((stats=get_file_size_time(argv[1]))==0)||(stats==-1))exit(1); if((dirp=opendir(argv[1]))==NULL) { printf("Open Directory %s Error :%s\n", argv[1],strerror(errno)); exit(1); } while((direntp=readdir(dirp))!=NULL) if(get_file_size_time(direntp-<d_name)==-1)break; closedir(dirp); exit(1); }
管道文件
管道pipe
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <errno.h> #include <sys/types.h> #include <sys/wait.h> #define BUFFER 255 int main(int argc,char **argv) { char buffer[BUFFER+1]; int fd[2]; if(argc!=2) { fprintf(stderr,"Usage:%s string\n\a",argv[0]); exit(1); } if(pipe(fd)!=0) { fprintf(stderr,"Pipe Error :%s\n\a",strerror(errno)); exit(1); } if(fork()==0) { close(fd[0]); printf("Child[%d] Write to pipe\n\a",getpid()); snprintf(buffer,BUFFER,"%s",argv[1]); write(fd[1],buffer,strlen(buffer)); printf("Child[%d] Quit\n\a",getpid()); exit(0); } else { close(fd[1]); printf("Parent[%d] Read from pipe\n\a",getpid()); memset(buffer,'\0',BUFFER+1); read(fd[0],buffer,BUFFER); printf("Parent[%d] Read:%s\n",getpid(),buffer); exit(1); } }
重定向dup2
#include <unistd.h> #include <stdio.h> #include <errno.h> #include <fcntl.h> #include <string.h> #include <sys/types.h> #include <sys/stat.h> #define BUFFER_SIZE 1024 int main(int argc,char **argv) { int fd; char buffer[BUFFER_SIZE]; if(argc!=2) { fprintf(stderr,"Usage:%s outfilename\n\a",argv[0]); exit(1); } if((fd=open(argv[1],O_WRONLY|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR))==-1) { fprintf(stderr,"Open %s Error :%s\n\a",argv[1],strerror(errno)); exit(1); } if(dup2(fd,STDOUT_FILENO)==-1) { fprintf(stderr,"Redirect Standard Out Error :%s\n\a",strerror(errno)); exit(1); } fprintf(stderr,"Now,please input string"); fprintf(stderr,"(To quit use CTRL+D)\n"); while(1) { fgets(buffer,BUFFER_SIZE,stdin); if(feof(stdin))break; write(STDOUT_FILENO,buffer,strlen(buffer)); } exit(0); }
時間的表示
#include <time.h> time_t time(time_t *tloc); char *ctime(const time_t *clock);
時間的測量
#include <sys/time.h> #include <stdio.h> #include <math.h> void function() { unsigned int i,j; double y; for(i=0;i<1000;i++) for(j=0;j<1000;j++) y=sin((double)i); } main() { struct timeval tpstart,tpend; float timeuse; gettimeofday(&tpstart,NULL); function(); gettimeofday(&tpend,NULL); timeuse=1000000*(tpend.tv_sec-tpstart.tv_sec)+ tpend.tv_usec-tpstart.tv_usec; timeuse/=1000000; printf("Used Time:%f\n",timeuse); exit(0); }
計時器
#include <sys/time.h> #include <stdio.h> #include <unistd.h> #include <signal.h> #include <string.h> #define PROMPT " 時間已通過去了兩秒鐘\n\a" char *prompt=PROMPT; unsigned int len; void prompt_info(int signo) { write(STDERR_FILENO,prompt,len); } void init_sigaction(void) { struct sigaction act; act.sa_handler=prompt_info; act.sa_flags=0; sigemptyset(&act.sa_mask); sigaction(SIGPROF,&act,NULL); } void init_time() { struct itimerval value; value.it_value.tv_sec=2; value.it_value.tv_usec=0; value.it_interval=value.it_value; setitimer(ITIMER_PROF,&value,NULL); } int main() { len=strlen(prompt); init_sigaction(); init_time(); while(1); exit(0); }
#include <sys/types.h>
#include <signal.h>
#include <unistd.h>
int kill(pid_t pid,int sig);
kill系統調用負責向進程發送信號sig.
若是pid是正數,那麼向信號sig被髮送到進程pid.
若是pid等於 0, 那麼信號sig被髮送到因此和pid進程在同一個進程組的進程
若是pid等於-1,那麼信號發給全部的進程表中的進程,除了最大的哪一個進程號.
若是pid因爲-1,和0 同樣,只是發送進程組是-pid
int raise(int sig);
raise 系統調用向本身發送一個sig信號
unisigned int alarm(unsigned int seconds);
alarm 函數能夠在seconds秒後向本身發送一個SIGALRM 信號
//經常使用的信號屏蔽函數 #include <signal.h> int sigemptyset(sigset_t *set); int sigfillset(sigset_t *set); int sigaddset(sigset_t *set,int signo); int sigdelset(sigset_t *set,int signo); int sigismember(sigset_t *set,int signo); int sigprocmask(int how,const sigset_t *set,sigset_t *oset);
#include <signal.h> #include <stdio.h> #include <math.h> #include <stdlib.h> int main(int argc,char **argv) { double y; sigset_t intmask; int i,repeat_factor; if(argc!=2) { fprintf(stderr,"Usage:%s repeat_factor\n\a",argv[0]); exit(1); } if((repeat_factor=atoi(argv[1]))<1)repeat_factor=10; sigemptyset(&intmask); /* 將信號集合設置爲空 */ sigaddset(&intmask,SIGINT); /* 加入中斷 Ctrl+C 信號*/ while(1) { /* 阻塞信號,咱們不但願保存原來的集合因此參數爲NULL*/ sigprocmask(SIG_BLOCK,&intmask,NULL); fprintf(stderr,"SIGINT signal blocked\n"); for(i=0;i<repeat_factor;i++) y=sin((double)i); fprintf(stderr,"Blocked calculation is finished\n"); /* 取消阻塞 */ sigprocmask(SIG_UNBLOCK,&intmask,NULL); fprintf(stderr,"SIGINT signal unblocked\n"); for(i=0;i<repeat_factor;i++) y=sin((double)i); fprintf(stderr,"Unblocked calculation is finished\n"); } exit(0); }
sigaction 函數
#include <signal.h>; int sigaction(int signo,const struct sigaction *act,struct sigaction *oact); struct sigaction { (*sa_handler)(int signo); void (*sa_sigaction)(int siginfo_t *info,void *act); sigset_t sa_mask; int sa_flags; void (*sa_restore)(void); }
#include <signal.h> #include <stdio.h> #include <string.h> #include <errno.h> #include <unistd.h> #define PROMPT " 你想終止程序嗎?" char *prompt=PROMPT; void ctrl_c_op(int signo) { write(STDERR_FILENO,prompt,strlen(prompt)); } int main() { struct sigaction act; act.sa_handler=ctrl_c_op; sigemptyset(&act.sa_mask); act.sa_flags=0; if(sigaction(SIGINT,&act,NULL)<0) { fprintf(stderr,"Install Signal Action Error :%s\n\a",strerror(errno)); exit(1); } while(1); }
其餘信號函數
#include <unistd.h> #include <signal.h> int pause(void); int sigsuspend(const sigset_t *sigmask); #include <sigsetjmp> int sigsetjmp(sigjmp_buf env,int val); void siglongjmp(sigjmp_buf env,int val);
實例
#include <unistd.h> #include <stdio.h> #include <errno.h> #include <fcntl.h> #include <signal.h> #include <string.h> #include <pwd.h> #include <sys/types.h> #include <sys/stat.h> /* Linux 的默任我的的郵箱地址是 /var/spool/mail/ */ #define MAIL_DIR "/var/spool/mail/" /* 睡眠 10 秒鐘 */ #define SLEEP_TIME 10 #define MAX_FILENAME 255 unsigned char notifyflag=1; long get_file_size(const char *filename) { struct stat buf; if(stat(filename,&;buf)==-1) { if(errno==ENOENT) return 0; else return -1; } return (long)buf.st_size; } void send_mail_notify(void) { fprintf(stderr,"New mail has arrived\007\n"); } void turn_on_notify(int signo) { notifyflag=1; } void turn_off_notify(int signo) { notifyflag=0; } int check_mail(const char *filename) { long old_mail_size,new_mail_size; sigset_t blockset,emptyset; sigemptyset(&;blockset); sigemptyset(&;emptyset); sigaddset(&;blockset,SIGUSR1); sigaddset(&;blockset,SIGUSR2); old_mail_size=get_file_size(filename); if(old_mail_size<0)return 1; if(old_mail_size>0) send_mail_notify(); sleep(SLEEP_TIME); while(1) { if(sigprocmask(SIG_BLOCK,&;blockset,NULL)<0) return 1; while(notifyflag==0) sigsuspend(&;emptyset); if(sigprocmask(SIG_SETMASK,&;emptyset,NULL)<0) return 1; new_mail_size=get_file_size(filename); if(new_mail_size>old_ma il_size) send_mail_notify(); old_mail_size=new_mail_size; sleep(SLEEP_TIME); } } int main(void) { char mailfile[MAX_FILENAME]; struct sigaction newact; struct passwd *pw; if((pw=getpwuid(getuid()))==NULL) { fprintf(stderr,"Get Login Name Error :%s\n\a",strerror(errno)); exit(1); } strcpy(mailfile,MAIL_DIR); strcat(mailfile,pw->pw_name); newact.sa_handler=turn_on_notify; newact.sa_flags=0; sigemptyset(&;newact.sa_mask); sigaddset(&;newact.sa_mask,SIGUSR1); sigaddset(&;newact.sa_mask,SIGUSR2); if(sigaction(SIGUSR1,&;newact,NULL)<0) fprintf(stderr,"Turn On Error :%s\n\a",strerror(errno)); newact.sa_handler=turn_off_notify; if(sigaction(SIGUSR1,&;newact,NULL)<0) fprintf(stderr,"Turn Off Error :%s\n\a",strerror(errno)); check_mail(mailfile); exit(0); }
POSIX 無名信號量函數:
#include <semaphore.h>
int sem_init(sem_t *sem,int pshared,unsigned int value);
int sem_destroy(sem_t *sem);
int sem_wait(sem_t *sem);
int sem_trywait(sem_t *sem);
int sem_post(sem_t *sem);
int sem_getvalue(sem_t *sem);
System V信號量
信號量的主要用途是保護臨界資源(在一個時刻只被一個進程所擁有)
#include <stdio.h> #include <unistd.h> #include <limits.h> #include <errno.h> #include <string.h> #include <stdlib.h> #include <sys/stat.h> #include <sys/wait.h> #include <sys/ipc.h> #include <sys/sem.h> #define PERMS S_IRUSR|S_IWUSR void init_semaphore_struct(struct sembuf *sem,int semnum, int semop,int semflg) { /* 初始話信號量結構 */ sem->sem_num=semnum; sem->sem_op=semop; sem->sem_flg=semflg; } int del_semaphore(int semid) { /* 信號量並不隨程序的結束而被刪除,若是咱們沒刪除的話(將1 改成0) 能夠用ipcs 命令查看到信號量,用ipcrm 能夠刪除信號量的 */ #if 1 return semctl(semid,0,IPC_RMID); #endif } int main(int argc,char **argv) { char buffer[MAX_CANON],*c; int i,n; int semid,semop_ret,status; pid_t childpid; struct sembuf semwait,semsignal; if((argc!=2)||((n=atoi(argv[1]))<1)) { fprintf(stderr,"Usage:%s number\n\a",argv[0]); exit(1); } /* 使用 IPC_PRIVATE 表示由系統選擇一個關鍵字來建立 */ /* 建立之後信號量的初始值爲 0 */ if((semid=semget(IPC_PRIVATE,1,PERMS))==-1) { fprintf(stderr,"[%d] :Acess Semaphore Error:%s\n\a",getpid(),strerror(errno)); exit(1); } /* semwait 是要求資源的操做(-1) */ init_semaphore_struct(&semwait,0,-1,0); /* semsignal 是釋放資源的操做(+1) */ init_semaphore_struct(&semsignal,0,1,0); /* 開始的時候有一個系統資源(一個標準錯誤輸出) */ if(semop(semid,&semsignal,1)==-1) { fprintf(stderr,"[%d] :Increment Semaphore Error:%s\n\a",getpid(),strerror(errno)); if(del_semaphore(semid)==-1) fprintf(stderr,"[%d] :Destroy Semaphore Error:%s\n\a",getpid(),strerror(errno)); exit(1); } /* 建立一個進程鏈 */ for(i=0;i<n;i++) if(childpid=fork()) break; sprintf(buffer,"[i=%d]-->[Process=%d]-->[Parent=%d]-->[Child=%d]\n",i,getpid(),getppid(),childpid); c=buffer; /* 這裏要求資源,進入原子操做 */ while(((semop_ret=semop(semid,&semwait,1))==-1)&&(errno==EINTR)); if(semop_ret==-1) { fprintf(stderr,"[%d] :Decrement Semaphore Error:%s\n\a", getpid(),strerror(errno)); } else { while(*c!='\0')fputc(*c++,stderr); /* 原子操做完成,趕快釋放資源 */ while(((semop_ret=semop(semid,&semsignal,1))==-1)&&(errno==EINTR)); if(semop_ret==-1) fprintf(stderr,"[%d] :Increment Semaphore Error:%s\n\a",getpid(),strerror(errno)); } /* 不可以在其餘進程反問信號量的時候,咱們刪除了信號量 */ while((wait(&status)==-1)&&(errno==EINTR)); /* 信號量只可以被刪除一次的 */ if(i==1) if(del_semaphore(semid)==-1) fprintf(stderr,"[%d] :Destroy Semaphore Error:%s\n\a", getpid(),strerror(errno)); exit(0); }
System V消息隊列
//服務端 server.c #include <stdio.h> #include <string.h> #include <stdlib.h> #include <errno.h> #include <unistd.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/stat.h> #include <sys/msg.h> #define MSG_FILE "server.c" #define BUFFER 255 #define PERM S_IRUSR|S_IWUSR struct msgtype { long mtype; char buffer[BUFFER+1]; }; int main() { struct msgtype msg; key_t key; int msgid; if((key=ftok(MSG_FILE,'a'))==-1) { fprintf(stderr,"Creat Key Error:%s\a\n",strerror(errno)); exit(1); } if((msgid=msgget(key,PERM|IPC_CREAT|IPC_EXCL))==-1) { fprintf(stderr,"Creat Message Error :%s\a\n",strerror(errno)); exit(1); } while(1) { msgrcv(msgid,&msg,sizeof(struct msgtype),1,0); fprintf(stderr,"Server Receive :%s\n",msg.buffer); msg.mtype=2; msgsnd(msgid,&msg,sizeof(struct msgtype),0); } exit(0); } //客戶端(client.c) #include <stdio.h> #include <string.h> #include <stdlib.h> #include <errno.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> #include <sys/stat.h> #define MSG_FILE "server.c" #define BUFFER 255 #define PERM S_IRUSR|S_IWUSR struct msgtype { long mtype; char buffer[BUFFER+1]; }; int main(int argc,char **argv) { struct msgtype msg; key_t key; int msgid; if(argc!=2) { fprintf(stderr,"Usage:%s string\n\a",argv[0]); exit(1); } if((key=ftok(MSG_FILE,'a'))==-1) { fprintf(stderr,"Creat Key Error:%s\a\n",strerror(errno)); exit(1); } if((msgid=msgget(key,PERM))==-1) { fprintf(stderr,"Creat Message Error :%s\a\n",strerror(errno)); exit(1); } msg.mtype=1; strncpy(msg.buffer,argv[1],BUFFER); msgsnd(msgid,&msg,sizeof(struct msgtype),0); memset(&msg,'\0',sizeof(struct msgtype)); msgrcv(msgid,&msg,sizeof(struct msgtype),2,0); fprintf(stderr,"Client receive :%s\n",msg.buffer); exit(0); }
System V共享內存
實現共享內存的幾個函數:
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
int shmget(key_t key,int size,int shmflg);
void *shmat(int shmid,const void *shmaddr,int shmflg);
int shmdt(const void *shmaddr);
int shmctl(int shmid,int cm d,struct shmid_ds *buf);
#include <stdio.h> #include <string.h> #include <errno.h> #include <unistd.h> #include <sys/stat.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h> #define PERM S_IRUSR|S_IWUSR int main(int argc,char **argv) { int shmid; char *p_addr,*c_addr; if(argc!=2) { fprintf(stderr,"Usage:%s\n\a",argv[0]); exit(1); } if((shmid=shmget(IPC_PRIVATE,1024,PERM))==-1) { fprintf(stderr,"Create Share Memory Error :%s\n\a",strerror(errno)); exit(1); } if(fork()) { p_addr=shmat(shmid,0,0); memset(p_addr,'\0',1024); strncpy(p_addr,argv[1],1024); exit(0); } else { c_addr=shmat(shmid,0,0); printf("Client get %s",c_addr); exit(0); } }
線程相關處理函數:
#include <pthread.h>
int pthread_create(pthread_t *thread,pthread_attr_t *attr, void *(*start_routine)(void *),void *arg);
void pthread_exit(void *retval);
int pthread_join(pthread *thread,void **thread_return);
#include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <string.h> #include <errno.h> #include <pthread.h> #include <dirent.h> #include <fcntl.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/time.h> #define BUFFER 512 struct copy_file { int infile; int outfile; }; void *copy(void *arg) { int infile,outfile; int bytes_read,bytes_write,*bytes_copy_p; char buffer[BUFFER],*buffer_p; struct copy_file *file=(struct copy_file *)arg; infile=file->infile; outfile=file->outfile; /* 由於線程退出時,全部的變量空間都要被釋放,因此咱們只好本身分配內存了 */ if((bytes_copy_p=(int *)malloc(sizeof(int)))==NULL) pthread_exit(NULL); bytes_read=bytes_write=0; *bytes_copy_p=0; /* 還記得怎麼拷貝文件嗎 */ while((bytes_read=read(infile,buffer,BUFFER))!=0) { if((bytes_read==-1)&&(errno!=EINTR))break; else if(bytes_read>0) { buffer_p=buffer; while((bytes_write=write(outfile,buffer_p,bytes_read))!=0) { if((bytes_write==-1)&&(errno!=EINTR))break; else if(bytes_write==bytes_read)break; else if(bytes_write>0) { buffer_p+=bytes_write; bytes_read-=bytes_write; } } if(bytes_write==-1)break; *bytes_copy_p+=bytes_read; } } close(infile); close(outfile); pthread_exit(bytes_copy_p); } int main(int argc,char **argv) { pthread_t *thread; struct copy_file *file; int byte_copy,*byte_copy_p,num,i,j; char filename[BUFFER]; struct dirent **namelist; struct stat filestat; /* 獲得當前路徑下面全部的文件(包含目錄)的個數 */ if((num=scandir(".",&namelist,0,alphasort))<0) { fprintf(stderr,"Get File Num Error :%s\n\a",strerror(errno)); exit(1); } /* 給線程分配空間,其實沒有必要這麼多的 */ if(((thread=(pthread_t *)malloc(sizeof(pthread_t)*num))==NULL)||((file=(struct copy_file *)malloc(sizeof(struct copy_file)*num))==NULL)) { fprintf(stderr,"Out Of Memory!\n\a"); exit(1); } for(i=0,j=0;i<num;i++) { memset(filename,'\0',BUFFER); strcpy(filename,namelist->d_name); if(stat(filename,&filestat)==-1) { fprintf(stderr,"Get File Information :%s\n\a",strerror(errno)); exit(1); } /* 咱們忽略目錄 */ if(!S_ISREG(filestat.st_mode))continue; if((file[j].infile=open(filename,O_RDONLY))<0) { fprintf(stderr,"Open %s Error :%s\n\a",filename,strerror(errno)); continue; } strcat(filename,".bak"); if((file[j].outfile=open(filename,O_W RONLY|O_CREAT,S_IRUSR|S_IWUSR))<0) { fprintf(stderr,"Creat %s Error :%s\n\a",filename,strerror(errno)); continue; } /* 建立線程,進行文件拷貝 */ if(pthread_create(&thread[j],NULL,copy,(void *)&file[j])!=0) fprintf(stderr,"Create Thread[%d] Error :%s\n\a",i,strerror(errno)); j++; } byte_copy=0; for(i=0;i<j;i++) { /* 等待線程結束 */ if(pthread_join(thread,(void **)&byte_copy_p)!=0) fprintf(stderr,"Thread[%d] Join Error :%s\n\a",i,strerror(errno)); else { if(bytes_copy_p==NULL)continue; printf("Thread[%d] Copy %d bytes\n\a",i,*byte_copy_p); byte_copy+=*byte_copy_p; /* 釋放咱們在 copy 函數裏面建立的內存 */ free(byte_copy_p); } } printf("Total Copy Bytes %d\n\a",byte_copy); free(thread); free(file); exit(0); }
/******* 服務器程序 (server.c) ************/ #include <stdlib.h> #include <stdio.h> #include <errno.h> #include <string.h> #include <netdb.h> #include <sys/types.h> #include <netinet/in.h> #include <sys/socket.h> int main(int argc, char *argv[]) { int sockfd,new_fd; struct sockaddr_in server_addr; struct sockaddr_in client_addr; int sin_size,portnumber; char hello[]="Hello! Are You Fine?\n"; if(argc!=2) { fprintf(stderr,"Usage:%s portnumber\a\n",argv[0]); exit(1); } if((portnumber=atoi(argv[1]))<0) { fprintf(stderr,"Usage:%s portnumber\a\n",argv[0]); exit(1); } /* 服務器端開始創建 socket 描述符 */ if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1) { fprintf(stderr,"Socket error :%s\n\a",strerror(errno)); exit(1); } /* 服務器端填充 sockaddr 結構 */ bzero(&server_addr,sizeof(struct sockaddr_in)); server_addr.sin_family=AF_INET; server_addr.sin_addr.s_addr=htonl(INADDR_ANY); server_addr.sin_port=htons(portnumber); /* 捆綁 sockfd 描述符 */ if(bind(sockfd,(struct sockaddr *)(& server_addr),sizeof(struct sockaddr))== -1) { fprintf(stderr,"Bind error :%s\n\a",strerror(errno)); exit(1); } /* 監聽 sockfd 描述符 */ if(listen(sockfd,5)==-1) { fprintf(stderr,"Listen error:%s\n\a",strerror(errno)); exit(1); } while(1) { /* 服務器阻塞,直到客戶程序創建鏈接 */ sin_size=sizeof(struct sockaddr_in); if((new_fd=accept(sockfd,(struct so ckaddr *)(&client_addr),&sin_size))==-1) { fprintf(stderr,"Accept error :%s\n\a",strerror(errno)); exit(1); } fprintf(stderr,"Server get connection from %s\n", inet_ntoa(client_addr.sin_addr)); if(write(new_fd,hello,strlen(hello))==-1) { fprintf(stderr,"Write Error:%s\n",strerror(errno)); exit(1); } /* 這個通信已經結束 */ close(new_fd); /* 循環下一個 */ } close(sockfd); exit(0); } /******* 客戶端程序 client.c ************/ #include <stdlib.h> #include <stdio.h> #include <errno.h> #include <string.h> #include <netdb.h> #include <sys/types.h> #include <netinet/in.h> #include <sys/socket.h> int main(int argc, char *argv[]) { int sockfd; char buffer[1024]; struct sockaddr_in server_addr; struct hostent *host; int portnumber,nbytes; if(argc!=3) { fprintf(stderr,"Usage:%s hostname portnumber\a\n",argv[0]); exit(1); } if((host=gethostbyname(argv[1]))==NULL) { fprintf(stderr,"Gethostname error\n"); exit(1); } if((portnumber=atoi(argv[2]))<0) { fprintf(stderr,"Usage:%s hostname portnumber\a\n",argv[0]); exit(1); } /* 客戶程序開始創建 sockfd描述符 */ if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1) { fprintf(stderr,"Socket Error :%s\a\n",strerror(errno)); exit(1); } /* 客戶程序填充服務端的資料 */ bzero(&server_addr,sizeof(server_addr)); server_addr.sin_family=AF_INET; server_addr.sin_port=htons(portnumber); server_addr.sin_addr=*((struct in_addr *)host->h_addr); /* 客戶程序發起鏈接請求 */ if(connect(sockfd,(struct sockaddr *)(& server_addr),sizeof(struct sockaddr))==-1) { fprintf(stderr,"Connect Error :%s\a\n",strerror(errno)); exit(1); } /* 鏈接成功了 */ if((nbytes=read(sockfd,buffer,1024))==-1) { fprintf(stderr,"Read Error:%s\n",strerror(errno)); exit(1); } buffer[nbytes]='\0'; printf("I have received :%s\n",buffer); /* 結束通信 */ close(sockfd); exit(0); }
完整版請參考: Linux操做系統下C語言編程入門