av一区二区在线观看_亚洲男人的天堂网站_日韩亚洲视频_在线成人免费_欧美日韩精品免费观看视频_久草视

您的位置:首頁技術(shù)文章
文章詳情頁

UNIX進(jìn)程之間的通信

瀏覽:140日期:2024-06-30 13:12:19

Unix進(jìn)程之間的通信進(jìn)程通訊是unix中很重要的知識。產(chǎn)生一個(gè)新的進(jìn)程主要有以下3種方法: 1,fork調(diào)用; 2,System調(diào)用; 3,Exec調(diào)用; 我們常說的進(jìn)程通訊編程主要有以下3種方法: 1,Message queue隊(duì)列編程; 2,Tcp/IP socket編程; 3,共享內(nèi)存編程; 一、進(jìn)程調(diào)用 1,產(chǎn)生進(jìn)程Fork調(diào)用例子: fork() 功能:創(chuàng)建一個(gè)新的進(jìn)程. 語法:#include <unistd.h> #include <sys/types.h> pid_t fork(); 說明:本系統(tǒng)調(diào)用產(chǎn)生一個(gè)新的進(jìn)程, 叫子進(jìn)程, 是調(diào)用進(jìn)程的一個(gè)復(fù)制品. 調(diào)用進(jìn)程叫父進(jìn)程, 子進(jìn)程繼承了父進(jìn)程的幾乎所有的屬性: . 實(shí)際UID,GID和有效UID,GID. . 環(huán)境變量. . 附加GID. . 調(diào)用exec()時(shí)的關(guān)閉標(biāo)志. . UID設(shè)置模式比特位. . GID設(shè)置模式比特位. . 進(jìn)程組號. . 會(huì)話ID. . 控制終端. . 當(dāng)前工作目錄. . 根目錄. . 文件創(chuàng)建掩碼UMASK. . 文件長度限制ULIMIT. . 預(yù)定值, 如優(yōu)先級和任何其他的進(jìn)程預(yù)定參數(shù), 根據(jù)種類不同決定是否可以繼承. . 還有一些其它屬性. 但子進(jìn)程也有與父進(jìn)程不同的屬性: . 進(jìn)程號, 子進(jìn)程號不同與任何一個(gè)活動(dòng)的進(jìn)程組號. . 父進(jìn)程號. . 子進(jìn)程繼承父進(jìn)程的文件描述符或流時(shí), 具有自己的一個(gè)拷貝并且與父進(jìn)程和其它子進(jìn)程共享該資源. . 子進(jìn)程的用戶時(shí)間和系統(tǒng)時(shí)間被初始化為0. . 子進(jìn)程的超時(shí)時(shí)鐘設(shè)置為0. . 子進(jìn)程的信號處理函數(shù)指針組置為空. . 子進(jìn)程不繼承父進(jìn)程的記錄鎖. 返回值: 調(diào)用成功則對子進(jìn)程返回0, 對父進(jìn)程返回子進(jìn)程號, 這也是最方便的區(qū)分父子進(jìn)程的方法. 若調(diào)用失敗則返回-1給父進(jìn)程,子進(jìn)程不生成. 2,產(chǎn)生進(jìn)程system調(diào)用例子: 功能:產(chǎn)生一個(gè)新的進(jìn)程, 子進(jìn)程執(zhí)行指定的命令. 語法:#include <stdio.h> #include <stdlib.h> int system(string) char *string; 說明:本調(diào)用將參數(shù)string傳遞給一個(gè)命令解釋器(一般為sh)執(zhí)行, 即string被解釋為一條命令, 由sh執(zhí)行該命令.若參數(shù)string為一個(gè)空指針則為檢查命令解釋器是否存在.該命令可以同命令行命令相同形式, 但由于命令做為一個(gè)參數(shù)放在系統(tǒng)調(diào)用中, 應(yīng)注意編譯時(shí)對特殊意義字符的處理. 命令的查找是按PATH環(huán)境變量的定義的. 命令所生成的后果一般不會(huì)對父進(jìn)程造成影響.返回值:當(dāng)參數(shù)為空指針時(shí), 只有當(dāng)命令解釋器有效時(shí)返回值為非零.若參數(shù)不為空指針, 返回值為該命令的返回狀態(tài)(同waitpid())的返回值. 命令無效或語法錯(cuò)誤則返回非零值,所執(zhí)行的命令被終止. 其他情況則返回-1. [code:1:d22bc4f5e9]例子1:char command[81]; int i; for (i=1;i<8;i++) { sprintf(command,'ps -t tty%02i',i); system(command); } 例子2: char befehl[200]; /* string buffer for csh command */ char *runserver = 'hosts1'; /* server name */ short shift_act_l; /* currect shift number */ char shift_act_c[1]; char shift_beg[20]; /* shift begin */ char shift_end[20]; /* shift end */ .... T_report_p->shift_no='0'; memcpy(T_report_p->time_from,'yyyy-mm-dd hh:mi:ss',sizeof(T_report_p->time_from)); memcpy(T_report_p->time_to,'yyyy-mm-dd hh:mi:ss',sizeof(T_report_p->time_to)); memset(befehl, '', sizeof(befehl)); sprintf (befehl, 'rsh %s %sprot.sh '%s %s %c '%19.19s' '%19.19s' '%9.9s' 0' &', runserver, REPORT_RSH_PATH, PROD_LOG, DRUCKER_NAME_1, T_report_p->shift_no, T_report_p->time_from, T_report_p->time_to, T_report_p->coil_id ); system (befehl); 3,產(chǎn)生進(jìn)程exec()調(diào)用例子: exec() 功能:執(zhí)行一個(gè)文件 語法:#include <unistd.h> int execl(path,arg0,...,argn,(char*)0) char *path,*arg0,...,*argn; int execv(path,argv) char *path,*argv[]; int execle(path,arg0,...,argn,(char*)0,envp) char *path,*arg0,...,*argn,*envp[]; int execve(path,argv,envp) char *path,*argv[],*envp[]; int execvp(file,argv) char *file,*argv[];[/code:1:d22bc4f5e9] 說明:這是一個(gè)系統(tǒng)調(diào)用族, 用于將一個(gè)新的程序調(diào)入本進(jìn)程所占的內(nèi)存, 并覆蓋之, 產(chǎn)生新的內(nèi)存進(jìn)程映象. 新的程序可以是可執(zhí)行文件或SHELL批命令.當(dāng)C程序被執(zhí)行時(shí),是如下調(diào)用的: main(int argc,char *argv[],char *envp[]); argc是參數(shù)個(gè)數(shù),是各個(gè)參數(shù)字符串指針數(shù)組,envp是新進(jìn)程的環(huán)境變量字符串的指針數(shù)組.argc至少為1, argv[0]為程序文件名,所以,在上面的exec系統(tǒng)調(diào)用族中,path為新進(jìn)程文件的路徑名,file為新進(jìn)程文件名,若file不是全路徑名,系統(tǒng)調(diào)用會(huì)按PATH環(huán)境變量自動(dòng)找對應(yīng)的可執(zhí)行文件運(yùn)行.若新進(jìn)程文件不是一個(gè)可執(zhí)行的目標(biāo)文件(如批處理文件),則execlp()和execvp()會(huì)將該文件內(nèi)容作為一個(gè)命令解釋器的標(biāo)準(zhǔn)輸入形成system().arg0,...等指針指向''結(jié)束的字符串,組成新進(jìn)程的有效參數(shù),且該參數(shù)列表以一個(gè)空指針結(jié)束.反過來,arg0至少必須存在并指向新進(jìn)程文件名或路徑名.同樣,argv是字符串指針數(shù)組,argv[0]指向新進(jìn)程文件名或路徑名,并以一空指針結(jié)束.envp是一個(gè)字符串指針數(shù)組,以空指針結(jié)束,這些字符串組成新進(jìn)程的環(huán)境.在調(diào)用這些系統(tǒng)調(diào)用前打開的文件指針對新進(jìn)程來說也是打開的,除非它已定義了close-on-exec標(biāo)志.打開的文件指針在新進(jìn)程中保持不變,所有相關(guān)的文件鎖也被保留.調(diào)用進(jìn)程設(shè)置并正被捕俘的信號在新進(jìn)程中被恢復(fù)為缺省設(shè)置,其它的則保持不變.新進(jìn)程啟動(dòng)時(shí)按文件的SUID和SGID設(shè)置定義文件的UID和GID為有效UID和GID.新進(jìn)程還繼承了如下屬性: . 附加GID. . 進(jìn)程號. . 父進(jìn)程號. . 進(jìn)程組號. . 會(huì)話號. . 控制終端. . alarm時(shí)鐘信號剩下的時(shí)間. . 當(dāng)前工作目錄. . 根目錄. . 文件創(chuàng)建掩碼. . 資源限制. . 用戶時(shí)間,系統(tǒng)時(shí)間,子進(jìn)程用戶時(shí)間,子進(jìn)程系統(tǒng)時(shí)間. . 記錄鎖. . 進(jìn)程信號掩碼. . 信號屏蔽. . 優(yōu)先級. . 預(yù)定值. 調(diào)用成功后,系統(tǒng)調(diào)用修改新進(jìn)程文件的最新訪問時(shí)間.返回值:該系統(tǒng)調(diào)用一般不會(huì)有成功返回值, 因?yàn)樵瓉淼倪M(jìn)程已蕩然無存. 例子:printf('now this process will be ps commandn'); execl('/bin/ps','ps','-ef',NULL); 二、進(jìn)程通訊編程 [code:1:d22bc4f5e9]1,Message queue隊(duì)列編程例子 /***************************************************************************** Excerpt from 'Linux Programmer's Guide - Chapter 6' (C)opyright 1994-1995, Scott Burkett ***************************************************************************** MODULE: msgtool.c ***************************************************************************** A command line tool for tinkering with SysV style Message Queues *****************************************************************************/ #include <stdio.h> #include <stdlib.h> #include <ctype.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> #define MAX_SEND_SIZE 80 struct mymsgbuf { long mtype; char mtext[MAX_SEND_SIZE]; }; void send_message(int qid, struct mymsgbuf *qbuf, long type, char *text); void read_message(int qid, struct mymsgbuf *qbuf, long type); void remove_queue(int qid); void change_queue_mode(int qid, char *mode); void usage(void); int main(int argc, char *argv[]) { key_t key; int msgqueue_id; struct mymsgbuf qbuf; if(argc == 1) usage(); /* Create unique key via call to ftok() */ /* key = ftok('.', 'w'); */ key = 123456; printf('key=%dn',key); key=IPC_PRIVATE; /* Open the queue - create if necessary */ if((tolower(argv[1][0]))!='s') { if((msgqueue_id = msgget(key, IPC_CREAT|0666)) == -1) { perror('msgget'); exit(1); } printf('msgqueue_id=%dn',msgqueue_id); } switch(tolower(argv[1][0])) { case 's': send_message(atoi(argv[4]), (struct mymsgbuf *)&qbuf, atol(argv[2]), argv[3]); break; case 'r': read_message(msgqueue_id, &qbuf, atol(argv[2])); break; case 'd': remove_queue(atoi(argv[2])); remove_queue(msgqueue_id); break; case 'm': change_queue_mode(msgqueue_id, argv[2]); break; default: usage(); } return(0); } void send_message(int qid, struct mymsgbuf *qbuf, long type, char *text) { printf('msgqueue_id=%dn',qid); /* Send a message to the queue */ printf('Sending a message ...n'); qbuf->mtype = type; strcpy(qbuf->mtext, text); printf(' Type: %ld Text: %sn', qbuf->mtype, qbuf->mtext); if((msgsnd(qid, (struct msgbuf *)qbuf, strlen(qbuf->mtext)+1, 0)) ==-1) { perror('msgsnd'); exit(1); } } void read_message(int qid, struct mymsgbuf *qbuf, long type) { /* Read a message from the queue */ printf('Reading a message ...n'); qbuf->mtype = type; msgrcv(qid, (struct msgbuf *)qbuf, MAX_SEND_SIZE, type, 0); printf(' Type: %ld Text: %sn', qbuf->mtype, qbuf->mtext); } void remove_queue(int qid) { /* Remove the queue */ msgctl(qid, IPC_RMID, 0); } void change_queue_mode(int qid, char *mode) { struct msqid_ds myqueue_ds; /* Get current info */ msgctl(qid, IPC_STAT, &myqueue_ds); /* Convert and load the mode */ sscanf(mode, '%ho', &myqueue_ds.msg_perm.mode); /* Update the mode */ msgctl(qid, IPC_SET, &myqueue_ds); } void usage(void) { fprintf(stderr, 'msgtool - A utility for tinkering with msg queuesn'); fprintf(stderr, 'nUSAGE: msgtool (s)end <type> <messagetext> <msgid>n'); fprintf(stderr, ' (r)ecv <type>n'); fprintf(stderr, ' (d)eleten'); fprintf(stderr, ' (m)ode <octal mode>n'); fprintf(stderr, 'note: type must be number!n'); exit(1); } 2,Tcp/IP socket編程例子 1), ClIEnt方 #include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <netdb.h> int main(int argc, char *argv[]) { int sockfd ,newsockfd, help, sent; struct sockaddr_in peer; struct hostent *serverhost; char buff[5000]; if(argc<2) { fprintf(stderr, 'Usage: coc <hostname>n'); exit(1); } if ((sockfd = socket(AF_INET,SOCK_STREAM,0)) < 0 ) { perror('socket'); exit(1); } if((serverhost = gethostbyname(argv[1])) == 0) { perror('gethostbyname'); exit(1); } peer.sin_family = AF_INET; peer.sin_port = htons(10000); peer.sin_addr = *(struct in_addr*)serverhost->h_addr_list[0]; if (connect(sockfd, &peer, sizeof(peer)) < 0 ) { perror('connect'); exit(1); } for(help=0; help<sizeof(buff); help++) buff[help] = '0'+help%10; write(sockfd, buff, 5000); close(sockfd); } 2, Server方 #include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> void process(int fd) { char buff[10000]; int received; int help,read_bytes; received = 5000; memset ( buff, '.', received ); read_bytes = read(fd, buff, received); if (read_bytes < 0) { perror('read'); exit(1); } printf('%d bytes have received on socket %dn', read_bytes, fd); printf('buff=n%sn', buff); for(help=0; help<received; help++) if(buff[help] != '0'+help%10) { printf('Error on position %dn', help); break; } } int main(void) { int sockfd ,newsockfd; struct sockaddr_in myaddr, peer; int addrlen1,addrlen2; if ((sockfd = socket(AF_INET,SOCK_STREAM,0)) < 0 ) { perror('socket'); exit(1); } addrlen1 = sizeof(myaddr); myaddr.sin_family = AF_INET; myaddr.sin_port = htons(10000); myaddr.sin_addr.s_addr = INADDR_ANY; if (bind(sockfd, &myaddr , addrlen1) < 0 ) { perror('bind'); exit(1); } if (listen(sockfd, 5 )) { perror('listen'); exit(1); } for (;;) { addrlen2 = sizeof(peer); newsockfd = accept(sockfd, &peer , &addrlen2); if ( newsockfd < 0) { perror('accept'); exit(1); } if (fork() == 0) { close(sockfd); /* process request */ printf('connection on socket %d from %sn', newsockfd, inet_ntoa(peer.sin_addr.s_addr)); process(newsockfd); close(newsockfd); exit(0); } close(newsockfd); } } 3,共享內(nèi)存編程例子 例子1: #include <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h> #define SHMKEY 74 #define K 1024 int shmid; cleanup() { shmctl(shmid,IPC_RMID,0); exit(0); } main() { int *pint; char *addr1,*addr2; extern char *shmat(); extern cleanup(); for (i=0;i<20;i++) signal(i,cleanup); shmid=shmget(SHMKEY,128*K,0777|IPC_CREAT); addr1=shmat(shmid,0,0); addr2=shmat(shmid,0,0); printf('addr1 0x%x addr2 0x%xn',addr1,addr2); pint=(int*)addr1; for (i=0;i<256;i++) *pint++=i; pint=(int*)addr1; *pint=256; pint=(int*)addr2; for (i=0;i<256;i++) printf('index %dtvalue%dn',i,*pint++); shmdt(addr1); shmdt(addr2); pause(); } 例子2 1),創(chuàng)建和寫共享內(nèi)存: /* Includes */ #include <errno.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h> typedef struct { int tc_number; char ap_name[5]; char mymessage[20]; } COMM_TABLE; main() { /* local variables */ int ret= 0; key_t key; int i; int shm_id; int found = 0; COMM_TABLE *comm_reg; key = ftok('.','w'); /* create a share memory if not exist */ if ((shm_id = shmget(key ,sizeof(COMM_TABLE),IPC_CREAT|IPC_EXCL|0666)) == -1) { /* share memory has been created */ if ((shm_id = shmget(key , sizeof(COMM_TABLE),0)) == -1) { printf('error = %dn', errno); return (ret); } } comm_reg = (COMM_TABLE *) shmat(shm_id, (char *) 0, SHM_SHARE_MMU); comm_reg->tc_number= 56110563; } 2), 讀共享內(nèi)存,再刪除共享內(nèi)存: /* Includes */ #include <errno.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h> typedef struct { int tc_number; char ap_name[5]; char mymessage[20]; } COMM_TABLE; main() { /* local variables */ int ret= 0; key_t key; int i; int shm_id; int found = 0; COMM_TABLE *comm_reg; char * pointer; key = ftok('.','w'); /* share memory has been created */ if ((shm_id = shmget(key , sizeof(COMM_TABLE),0)) == -1) { printf('error = %dn', errno); return (ret); } comm_reg = (COMM_TABLE *) shmat(shm_id, (char *) 0, SHM_SHARE_MMU); printf('tc number=%d!!!n', comm_reg->tc_number); /* kill share memory */ shmctl(shm_id,IPC_RMID,0);

標(biāo)簽: Unix系統(tǒng)
主站蜘蛛池模板: 欧美色综合天天久久综合精品 | 久久av中文字幕 | a级黄色片 | 毛片视频免费 | 日韩免费精品 | 午夜精品视频在线观看 | 亚洲黄色在线 | 久久久久一区二区三区 | 一区二区三区四区在线视频 | 国产一级黄 | 国产精品一区二区久久 | 亚洲精品成人在线 | 精品一区二区三区四区五区 | 欧美一区二区三区的 | 成年人免费在线观看 | 国产操操操 | 综合网久久 | 欧美有码视频 | 亚洲精品免费在线 | 一区免费视频 | 91色交视频| 黄色激情视频网站 | 九九热在线精品 | 一区二区免费在线观看 | 成年人av | 99热思思| 在线观看av的网站 | 日本理伦片午夜理伦片 | 超碰在线中文字幕 | 欧美资源在线 | 成人午夜av| www.亚洲国产| 国产福利在线视频 | 欧美另类视频 | 日本中文字幕在线播放 | 一级片在线免费观看 | 国产精品欧美在线 | 日韩一区二区免费视频 | 国产乱码一区二区 | 久久精品一区二区国产 | 欧美视频在线观看一区 |