广州市花都区建设局网站济南企业网站建设公司
- 作者: 五速梦信息网
- 时间: 2026年04月20日 11:05
当前位置: 首页 > news >正文
广州市花都区建设局网站,济南企业网站建设公司,让你做一个旅游网站你会怎么做,什么网站代做毕业设计比较好学习参考博文#xff1a; 进程间的五种通信方式介绍Linux 信号介绍 Linux系统编程学习相关博文 Linux系统编程——文件编程的学习Linux系统编程——进程的学习Linux系统编程——线程的学习Linux系统编程——网络编程的学习 Linux系统编程——进程间通信的学习 一、概述1. 无…学习参考博文 进程间的五种通信方式介绍Linux 信号介绍 Linux系统编程学习相关博文 Linux系统编程——文件编程的学习Linux系统编程——进程的学习Linux系统编程——线程的学习Linux系统编程——网络编程的学习 Linux系统编程——进程间通信的学习 一、概述1. 无名管道和有名管道的区别2. 当打开一个FIFO时是否设置非阻塞标志O_NONBLOCK的区别3. 消息队列4. 共享内存5. 信号6. 信号量 二、进程间通信API三、API介绍1. pipe函数2. mkfifo函数3. msgget函数4. msgsnd函数5. msgrcv函数6. msgctl函数7. shmget函数8. shmat函数9. shmdt函数10. shmctl函数11. signal函数12. kill函数13. sigaction函数14. sigqueue函数15. semget函数16. semctl函数17. semop函数 四、API的使用例子1. pipe函数2. mkfifo函数3. msgget、msgsnd、msgrcv、msgctl函数4. shmget、shmat、shmdt、shmctl函数5. signal函数6. kill函数7. sigaction函数8. sigqueue函数9. semget、semctl、semop函数 一、概述 常规学习Linux系统编程的内容是复杂且繁多的不推荐刚开始接触代码的朋友去学习所以介绍Linux系统编程的目的主要是以应用开发为主。 进程间通信IPCInterProcess Communication是指在不同进程之间传播或交换信息。 IPC的方式通常有管道包括无名管道和命名管道、消息队列、信号量、共享存储、Socket、Streams等。其中 Socket和Streams支持不同主机上的两个进程IPC。
- 无名管道和有名管道的区别 无名管道是半双工的(即数据只能在一个方向上流动)具有固定的读端和写端。它只能用于具有亲缘关系的进程之间的通信(也是父子进程或者兄弟进程之间)它可以看成是一种特殊的文件对于它的读写也可以使用普通的read、write 等函数。但是它不是普通的文件并不属于其他任何文件系统并且只存在于内存中。有名管道可以在无关的进程之间交换数据与无名管道不同。
- 当打开一个FIFO时是否设置非阻塞标志O_NONBLOCK的区别 若没有指定O_NONBLOCK默认只读 open 要阻塞到某个其他进程为写而打开此 FIFO。类似的只写 open 要阻塞到某个其他进程为读而打开它。 若指定了O_NONBLOCK则只读 open 立即返回。而只写 open 将出错返回 -1 如果没有进程已经为读而打开该 FIFO其errno置ENXIO。
- 消息队列 消息队列是消息的链接表存放在内核中。消息队列独立于发送与接收进程。进程终止时消息队列及其内容并不会被删除。
- 共享内存 共享内存是最快的一种 IPC因为进程是直接对内存进行存取。因为多个进程可以同时操作所以需要进行同步。信号量共享内存通常结合在一起使用信号量用来同步对共享内存的访问。
- 信号 每个信号都有一个名字和编号这些名字都以“SIG”开头例如“SIGIO ”、“SIGCHLD”等等。信号定义在signal.h头文件中信号名都定义为正整数。具体的信号名称可以使用kill -l来查看信号的名字以及序号信号是从1开始编号的不存在0号信号。kill对于信号0又特殊的应用。信号的处理有三种方法分别是忽略、捕捉和默认动作
- 信号量 信号量semaphore与已经介绍过的 IPC 结构不同它是一个计数器。信号量用于实现进程间的互斥与同步而不是用于存储进程间通信数据。 信号量用于进程间同步若要在进程间传递数据需要结合共享内存。信号量基于操作系统的 PV 操作程序对信号量的操作都是原子操作。每次对信号量的 PV 操作不仅限于对信号量值加 1 或减 1而且可以加减任意正整数。(P操作相当于拿钥匙V操作相当于放钥匙)支持信号量组。 二、进程间通信API 在Linux系统中操作系统提供了一系列的API详细看下图
- 管道 创建无名管道 pipe() 创建有名管道 mkfifo()
- 消息队列 创建或打开消息队列 msgget() 添加消息 msgsnd() 读取消息 msgrcv() 控制消息队列 msgctl()
- 共享内存 创建或获取共享内存 shmget() 将共享内存映射到当前进程的虚拟地址空间 shmat() 断开与共享内存的连接 shmdt() 控制共享内存的相关信息 shmctl()
- 信号 信号处理函数 入门版 signal() / 高级版 sigaction() 信号发送函数 入门版 kill() / 高级版 sigqueue()
- 信号量 创建或获取信号量组 semget() 控制信号量的相关信息 semctl() 对信号量组进行操作 semop()三、API介绍
- pipe函数 #include unistd.hint pipe(int pipefd[2]);1. 函数功能创建无名管道
- 形参说明 pipefd[2]一个管道建立时它会创建两个文件描述符fd[0]为读而打开fd[1]为写而打开。
- 返回值成功返回0失败返回-12. mkfifo函数 #include sys/types.h #include sys/stat.hint mkfifo(const char *pathname, mode_t mode);1. 函数功能创建有名管道
- 形参说明 pathname文件路径名 mode与open函数中的mode相同。一旦创建了一个FIFO就可以用一般的文件I/O函数去操作它。(忘记的可以去文件编程学习篇章回顾下)
- 返回值成功返回0失败返回-13. msgget函数 #include sys/types.h #include sys/ipc.h #include sys/msg.hint msgget(key_t key, int msgflg);1. 函数功能创建或打开消息队列
- 形参说明 key键值key可自己写死也可用ftok函数生成(ftok函数具体看API使用例子了解) msgflg- 这个参数可以是单独的IPC_CREAT也可以是IPC_CREAT|IPC_EXCL但IPC_EXCL单独使用没有意义- 如果单独使用IPC_CREAT(记得附加权限)或者flg为0创建一个消息队列如果创建的消息队列已经存在则返回已经存在的队列ID不存在则创建 - IPC_CREAT | IPC_EXCL如果不存在消息队列则创建如果已经有了消息队列则返回-1
- 返回值成功返回队列ID失败返回-14. msgsnd函数 #include sys/types.h #include sys/ipc.h #include sys/msg.hint msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);1. 函数功能添加消息
- 形参说明 msqid队列ID msgpmsgp参数是一个指针指向调用者定义的结构体其一般形式如下:struct msgbuf {long mtype; /* message type, must be 0 /char mtext[1]; / message data */};mtext字段是一个数组(或其他结构)其大小由非负整数值msgsz指定。允许零长度的消息(即没有mtext字段)。mtype字段必须是严格的正整数值。接收进程可以使用此值进行消息选择 msgsz指定msgp结构体里边mtext参数的大小 msgflg默认是0
- 返回值成功返回0失败返回-15. msgrcv函数 #include sys/types.h #include sys/ipc.h #include sys/msg.hssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);1. 函数功能读取消息
- 形参说明 msqid队列ID msgpmsgp参数是一个指针指向调用者定义的结构体其一般形式如下:struct msgbuf {long mtype; /* message type, must be 0 /char mtext[1]; / message data */}; msgsz读取数据的大小 msgtypmtype字段必须是严格的正整数值。接收进程可以使用此值进行消息选择 msgflgmsgflg参数是一个位掩码由以下零个或多个标志组合而成:· IPC_NOWAIT如果队列中没有请求类型的消息则立即返回· MSG_EXCEPT当msgtyp大于0时用于读取消息类型与msgtyp不同的队列中的第一条消息。· MSG_NOERROR如果消息文本长度超过msgsz字节则截断消息文本。· 为0时是默认状态当没有消息类型与msgtyp相同的队列发送信息时则一直阻塞
- 返回值成功返回消息数据的长度失败返回-16. msgctl函数 #include sys/types.h #include sys/ipc.h #include sys/msg.hint msgctl(int msqid, int cmd, struct msqid_ds *buf)1. 函数功能控制消息队列
- 形参说明 msqid队列ID cmdIPC_RMID————从内核中删除消息队列(其他参数请自行查阅) buf控制消息队列时数据处理的结构体(默认是NULL)
- 返回值成功返回0失败返回-17. shmget函数 #include sys/ipc.h #include sys/shm.hint shmget(key_t key, size_t size, int shmflg);1. 函数功能创建或获取共享内存
- 形参说明 key键值key可自己写死也可用ftok函数生成(ftok函数具体看API使用例子了解) size当用shmget函数创建一段共享内存时必须指定其 size而如果引用一个已存在的共享内存则将 size 指定为0 。 shmflg- 这个参数可以是单独的IPC_CREAT也可以是IPC_CREAT|IPC_EXCL但IPC_EXCL单独使用没有意义- 如果单独使用IPC_CREAT(记得附加权限)或者flg为0创建一个共享内存如果创建的共享内存已经存在则返回已经存在的共享内存ID不存在则创建 - IPC_CREAT | IPC_EXCL如果不存在共享内存则创建如果已经有了共享内存则返回-1
- 返回值成功返回共享内存ID失败返回-18. shmat函数 #include sys/types.h #include sys/shm.hvoid *shmat(int shmid, const void *shmaddr, int shmflg);1. 函数功能将共享内存映射到当前进程的虚拟地址空间
- 形参说明 shmid共享内存ID shmaddr该参数常用的是NULL。如果shmadr为NULL系统选择一个合适的(未使用的)地址来附加该段 shmflg该形参作用是权限附加常用的是0。如果为0系统默认映射进来的共享内存为可读可写权限
- 返回值成功返回指向共享内存的指针失败返回-19. shmdt函数 #include sys/types.h #include sys/shm.hint shmdt(const void *shmaddr);1. 函数功能断开与共享内存的连接
- 形参说明 shmaddr映射后返回共享内存的指针
- 返回值成功返回0失败返回-110. shmctl函数 #include sys/ipc.h #include sys/shm.hint shmctl(int shmid, int cmd, struct shmid_ds *buf);1. 函数功能控制共享内存的相关信息
- 形参说明 shmid共享内存ID cmd命令参数。常用的是IPC_RMID(从系统中删除该共享内存) buf该参数是卸载共享内存后所返回的一些信息。不关心为NULL
- 返回值成功返回0失败返回-111. signal函数 #include signal.htypedef void (*sighandler_t)(int); sighandler_t signal(int signum, sighandler_t handler);1. 函数功能信号处理函数
- 形参说明 signum监听的信号(kill -l参看) handler收到信号后处理的函数函数原型typedef void (*sighandler_t)(int);12. kill函数 #include sys/types.h #include signal.hint kill(pid_t pid, int sig);1. 函数功能信号发送函数
- 形参说明 pid发送信号时对方的pid号 sig要发送的信号(kill -l参看)
- 返回值成功返回0失败返回-113. sigaction函数 #include signal.hint sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);1. 函数功能信号处理函数(带数据)
- 形参说明 signum监听的信号(kill -l参看) act收到信号后处理的函数结构体原型struct sigaction {void (*sa_handler)(int);void (*sa_sigaction)(int, siginfo_t *, void *);sigset_t sa_mask;int sa_flags;void (sa_restorer)(void);};上面结构体里第二个函数指针第二个struct siginfo结构体的相关信息siginfo_t {int si_signo; / Signal number /int si_errno; / An errno value /int si_code; / Signal code /int si_trapno; / Trap number that causedhardware-generated signal(unused on most architectures) /pid_t si_pid; / Sending process ID /uid_t si_uid; / Real user ID of sending process /int si_status; / Exit value or signal /clock_t si_utime; / User time consumed /clock_t si_stime; / System time consumed /sigval_t si_value; / Signal value /int si_int; / POSIX.1b signal */void si_ptr; / POSIX.1b signal /int si_overrun; / Timer overrun count; POSIX.1b timers /int si_timerid; / Timer ID; POSIX.1b timers */void si_addr; / Memory location which caused fault /int si_band; / Band event /int si_fd; / File descriptor */} oldact该参数是数据备份。默认为NULL
- 返回值成功返回0失败返回-114. sigqueue函数 #include signal.hint sigqueue(pid_t pid, int sig, const union sigval value);1. 函数功能信号发送函数(带数据)
- 形参说明 pid发送信号时对方的pid号 sig要发送的信号(kill -l参看) value发送的数据联合体原型union sigval {int sival_int;void *sival_ptr;};
- 返回值成功返回0失败返回-115. semget函数 #include sys/types.h #include sys/ipc.h #include sys/sem.hint semget(key_t key, int nsems, int semflg);1. 函数功能创建或获取一个信号量组
- 形参说明 key键值key可自己写死也可用ftok函数生成(ftok函数具体看API使用例子了解) nsems信号量个数 semflg- 这个参数可以是单独的IPC_CREAT也可以是IPC_CREAT|IPC_EXCL但IPC_EXCL单独使用没有意义- 如果单独使用IPC_CREAT(记得附加权限)或者flg为0创建一个共享内存如果创建的共享内存已经存在则返回已经存在的共享内存ID不存在则创建 - IPC_CREAT | IPC_EXCL如果不存在共享内存则创建如果已经有了共享内存则返回-1
- 返回值成功返回信号量集ID失败返回-116. semctl函数 #include sys/types.h #include sys/ipc.h #include sys/sem.hint semctl(int semid, int semnum, int cmd, …);1. 函数功能控制信号量的相关信息
- 形参说明 semid信号量集id semnum操控哪个信号量 cmd命令参数。常用的是SETVAL这个函数有三个或四个参数具体取决于cmd。当有四个时第四个具有类型联合semur调用程序必须按如下方式定义这个联合体:union semun {int val; /* Value for SETVAL */struct semid_ds buf; / Buffer for IPC_STAT, IPC_SET */unsigned short array; / Array for GETALL, SETALL */struct seminfo __buf; / Buffer for IPC_INFO (Linux-specific) */};3. 返回值失败返回-117. semop函数 #include sys/types.h #include sys/ipc.h #include sys/sem.hint semop(int semid, struct sembuf *sops, unsigned nsops)1. 函数功能对信号量组进行操作
- 形参说明 semid信号量集id sopssops所指向的数组中的每个nsop元素都指定了要在单个信号量上执行的操作。该结构体的元素类型为struct sembuf包含以下成员:unsigned short sem_num; /* semaphore number /short sem_op; / semaphore operation /short sem_flg; / operation flags / nsops信号量集个数(决定第二个参数个数)该函数的使用例子struct sembuf sops[2];int semid;/ Code to set semid omitted /sops[0].sem_num 0; / Operate on semaphore 0 /sops[0].sem_op 0; / Wait for value to equal 0 /sops[0].sem_flg 0;sops[1].sem_num 0; / Operate on semaphore 0 /sops[1].sem_op 1; / Increment value by one */sops[1].sem_flg 0;if (semop(semid, sops, 2) -1) {perror(semop);exit(EXIT_FAILURE);}3. 返回值成功返回0失败返回-1四、API的使用例子
- pipe函数 1 #include stdio.h2 #include stdlib.h3 #include string.h4 5 #include unistd.h6 7 int main()8 {9 // int pipe(int pipefd[2]);10 11 int pid 0;12 int fd[2] {0};13 char buf[128] {0} ;14 15 if(pipe(fd) -1){ //创建管道16 printf(create pipe failed\n);17 perror(why);18 }19 20 pid fork(); //创建子进程21 22 if(pid 0){ 23 printf(create child failed\n);24 perror(why);25 }26 else if(pid 0){ //父进程27 sleep(1);28 29 printf(This is father\n);30 close(fd[0]); //关闭读端31 write(fd[1], Hello World, strlen(Hello World)); //写入数据32 33 wait(NULL);34 }35 else{ //子进程36 printf(This is child\n);37 close(fd[1]); //关闭写端38 read(fd[0], buf, sizeof(buf)); //读取数据39 printf(read data: %s\n, buf);40 41 exit(0);42 }43 44 return 0;45 }2. mkfifo函数 1 #include stdio.h2 #include stdlib.h3 #include string.h4 5 #include sys/types.h6 #include sys/stat.h7 #include errno.h8 #include fcntl.h9 10 int main()11 {12 // int mkfifo(const char *pathname, mode_t mode);13 int fd 0;14 15 if((mkfifo(./file, 0600) -1) errno ! EEXIST){ //创建管道16 printf(create failed\n);17 perror(why);18 }19 20 fd open(./file, O_RDONLY);21 22 return 0;23 }3. msgget、msgsnd、msgrcv、msgctl函数 接收端demo 1 #include stdio.h2 #include errno.h3 #include string.h4 #include stdlib.h5 6 #include sys/types.h7 #include sys/ipc.h8 #include sys/msg.h9 10 // 1. int msgget(key_t key, int msgflg);11 // 2. int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);12 // 3. ssize_t msgrcv(int msqid, void msgp, size_t msgsz, long msgtyp, int msgflg);13 14 struct msgbuf {15 long mtype; / message type, must be 0 /16 char mtext[128]; / message data */17 }18 19 int main()20 {21 int msgId;22 23 key_t key;24 25 struct msgbuf readBuf;26 struct msgbuf sendBuf {988, Welcome your coming};27 28 key ftok(., 23); //获取key29 printf(key 0x%x\n, key);30 31 msgId msgget(key, IPC_CREAT|0777); //创建消息队列32 33 if(msgId -1){34 printf(creat quene failed\n);35 perror(why);36 }37 38 msgrcv(msgId, readBuf, sizeof(readBuf.mtext), 888, 0); //读取消息39 printf(get message from quene, content: %s\n, readBuf.mtext);40 41 msgsnd(msgId, sendBuf, sizeof(sendBuf.mtext), 0); //发送消息42 43 msgctl(msgId, IPC_RMID, NULL); //删除消息队列44 45 return 0;46 }发送端 1 #include stdio.h2 #include errno.h3 #include string.h4 #include stdlib.h5 6 #include sys/types.h7 #include sys/ipc.h8 #include sys/msg.h9 10 // 1. int msgget(key_t key, int msgflg);11 // 2. int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);12 // 3. ssize_t msgrcv(int msqid, void msgp, size_t msgsz, long msgtyp, int msgflg);13 14 struct msgbuf {15 long mtype; / message type, must be 0 /16 char mtext[128]; / message data */17 };18 19 int main()20 {21 int msgId;22 23 key_t key;24 25 struct msgbuf readBuf;26 struct msgbuf sendBuf {888, This is content from quene};27 28 key ftok(., 23); //获取key29 printf(key 0x%x\n, key);30 31 msgId msgget(key, IPC_CREAT|0777); //创建消息队列32 33 if(msgId -1){34 printf(creat quene failed\n);35 perror(why);36 }37 38 msgsnd(msgId, sendBuf, sizeof(sendBuf.mtext), 0); //发送消息39 printf(Send over!\n);40 41 msgrcv(msgId, readBuf, sizeof(readBuf.mtext), 988, 0); //读取消息42 printf(get message from msgGet, content: %s\n, readBuf.mtext);43 44 msgctl(msgId, IPC_RMID, NULL);45 46 return 0;47 }4. shmget、shmat、shmdt、shmctl函数 接收端 1 #include stdio.h2 #include stdlib.h3 #include string.h4 5 #include sys/ipc.h6 #include sys/shm.h7 #include sys/types.h8 9 // 1. int shmget(key_t key, size_t size, int shmflg);10 // 2. void *shmat(int shmid, const void *shmaddr, int shmflg);11 // 3. int shmdt(const void *shmaddr);12 // 4. int shmctl(int shmid, int cmd, struct shmid_ds *buf);13 14 int main()15 {16 int shmid;17 char *shmaddr;18 19 key_t key;20 21 key ftok(., 1); //获取key22 23 shmid shmget(key, 1024*4, 0); //获取共享内存24 25 shmaddr shmat(shmid, NULL, 0); //映射26 27 printf(read: %s\n, shmaddr);28 29 shmdt(shmaddr); //断开共享内存30 31 printf(quit\n);32 33 return 0;34 }发送端 1 #include stdio.h2 #include stdlib.h3 #include string.h4 5 #include sys/ipc.h6 #include sys/shm.h7 #include sys/types.h8 9 // 1. int shmget(key_t key, size_t size, int shmflg);10 // 2. void *shmat(int shmid, const void *shmaddr, int shmflg);11 // 3. int shmdt(const void *shmaddr);12 // 4. int shmctl(int shmid, int cmd, struct shmid_ds *buf);13 14 int main()15 {16 int shmid;17 char *shmaddr;18 19 key_t key;20 21 key ftok(., 1); //获取key22 23 shmid shmget(key, 1024*4, IPC_CREAT|0666); //创建共享内存24 25 if(shmid -1){26 perror(create shm failed);27 exit(-1);28 }29 30 shmaddr shmat(shmid, NULL, 0); //映射31 32 strcpy(shmaddr, Hello World); //写入数据33 printf(write..\n);34 sleep(5);35 36 shmdt(shmaddr); //断开共享内存37 38 shmctl(shmid, IPC_RMID, NULL); //删除共享内存39 40 printf(quit\n);41 42 return 0;43 }5. signal函数 1 #include stdio.h2 #include stdlib.h3 #include string.h4 5 #include signal.h6 7 // typedef void (*sighandler_t)(int);8 // 1. sighandler_t signal(int signum, sighandler_t handler);9 10 void handler(int signum) //处理函数11 {12 switch(signum){13 case 2:14 printf(signum %d\n, signum);15 printf(never quit\n);16 17 break;18 case 9:19 printf(signum %d\n, signum);20 printf(never quit\n);21 22 break;23 case 10:24 printf(signum %d\n, signum);25 printf(never quit\n);26 27 break;28 default:29 printf(signum %d\n, signum);30 printf(never quit\n);31 32 break;33 }34 }35 36 int main()37 {38 signal(SIGHUP, handler); //捕获SIGHUP信号39 signal(SIGINT, handler); //捕获SIGINT信号40 signal(SIGKILL, handler); //捕获SIGKILL信号41 signal(SIGUSR1, handler); //捕获SIGUSR1信号42 43 while(1);44 45 return 0;46 }6. kill函数 1 #include stdio.h2 #include stdlib.h3 #include string.h4 5 #include signal.h6 #include sys/types.h7 8 // typedef void (*sighandler_t)(int);9 // 1. sighandler_t signal(int signum, sighandler_t handler);10 // 2. int kill(pid_t pid, int sig);11 12 int main(int argc, char **argv)13 {14 int pid;15 int signum;16 char cmd[32] /0;17 18 if(argc 3){19 printf(please input three param\n);20 exit(-1);21 }22 23 signum atoi(argv[1]); //将字符串转换成整型数(第二个参数)24 pid atoi(argv[2]); //将字符串转换成整型数(第三个参数)25 26 sprintf(cmd, kill -%d %d, signum, pid);27 //kill(pid, signum); //发送指令28 29 system(cmd); //发送指令30 31 return 0;32 }7. sigaction函数 1 #include stdio.h2 #include stdlib.h3 #include string.h4 5 #include sys/types.h6 #include unistd.h7 #include signal.h8 9 // 1. int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);10 11 void handler(int signum, siginfo_t *info, void *context) //处理函数12 {13 printf(\nsignum %d\n, signum);14 15 if(context ! NULL){16 printf(get data: %d\n, info-si_int);17 printf(get data: %d\n, info-si_value.sival_int);18 printf(from: %d\n,info-si_pid);19 }20 }21 22 int main()23 {24 struct sigaction act;25 26 printf(pid %d\n, getpid());27 28 act.sa_sigaction handler;29 act.sa_flags SA_SIGINFO; //如果在sa_flags中指定了SA SIGINFO则sa _sigaction(而不是sa_handler)指定signum的信号处理函数。30 31 sigaction(SIGUSR1, act, NULL); 捕获SIGUSR1信号32 33 while(1);34 35 return 0;36 }8. sigqueue函数 1 #include stdio.h2 #include stdlib.h3 #include string.h4 5 #include sys/types.h6 #include unistd.h7 #include signal.h8 9 // 1. int sigqueue(pid_t pid, int sig, const union sigval value);10 11 int main(int argc, char **argv)12 {13 int pid;14 int signum;15 16 pid atoi(argv[2]); //将字符串转换成整型数(第三个参数)17 signum atoi(argv[1]); //将字符串转换成整型数(第二个参数)18 19 union sigval value;20 value.sival_int 100; //发送的整形数据21 22 sigqueue(pid, signum, value); //发送函数23 24 printf(pid %d\n, getpid()); //打印pid号25 26 return 0;27 }9. semget、semctl、semop函数 1 #include stdio.h2 #include stdlib.h3 #include string.h4 5 #include sys/types.h6 #include sys/ipc.h7 #include sys/sem.h8 #include unistd.h9 10 // 1. int semget(key_t key, int nsems, int semflg);11 // 2. int semctl(int semid, int semnum, int cmd, …);12 // 3. int semop(int semid, struct sembuf sops, unsigned nsops);13 14 union semun {15 int val; / Value for SETVAL */16 struct semid_ds buf; / Buffer for IPC_STAT, IPC_SET */17 unsigned short array; / Array for GETALL, SETALL */18 struct seminfo __buf; / Buffer for IPC_INFO19 (Linux-specific) /20 };21 22 void pGetKey(int semid) //拿钥匙23 {24 struct sembuf sop;25 26 sop.sem_num 0; / Operate on semaphore 0 /27 sop.sem_op -1; / Wait for value to equal 0 /28 sop.sem_flg SEM_UNDO;29 30 semop(semid, sop, 1); //操作信号量31 32 printf(Get key\n);33 }34 35 void vPutBackKey(int semid) //放钥匙36 {37 struct sembuf sop;38 39 sop.sem_num 0; / Operate on semaphore 0 /40 sop.sem_op 1; / Wait for value to equal 0 */41 sop.sem_flg SEM_UNDO;42 43 semop(semid, sop, 1); //操作信号量44 45 printf(Put back key\n);46 }47 48 int main()49 {50 int pid;51 int semid;52 key_t key;53 54 union semun value;55 56 key ftok(., 23); //获取key57 58 //创建/获取一个信号量59 semid semget(key, 1, IPC_CREAT|0666); //创建信号量集60 61 value.val 0; //初始时盒子里没钥匙62 63 //控制信号量集64 semctl(semid, 0, SETVAL, value); //信号量集初始化65 66 pid fork(); //创建子进程67 68 if(pid 0){ //父进程69 // 拿钥匙——如果盒子里没钥匙父进程出于阻塞状态70 pGetKey(semid); //拿钥匙71 printf(This is father\n);72 // 放钥匙73 vPutBackKey(semid); //放钥匙74 }75 else if(pid 0){ //子进程76 printf(This is child\n);77 // 放钥匙——因初始化时盒子里没钥匙无论是不是父进程先运行它都会处于阻塞状态等子进程把放入钥匙后父进程才能拿钥匙开门78 vPutBackKey(semid); //放钥匙79 }80 else{81 printf(fork error\n);82 }83 84 return 0;85 }
- 上一篇: 广州市官网网站建设怎么样js弹出网站
- 下一篇: 广州市建设工程招标管理办公室网站蓝一互动网站建设
相关文章
-
广州市官网网站建设怎么样js弹出网站
广州市官网网站建设怎么样js弹出网站
- 技术栈
- 2026年04月20日
-
广州商务网站建设想做个网站怎么做
广州商务网站建设想做个网站怎么做
- 技术栈
- 2026年04月20日
-
广州商城建站在手机上怎么做app软件
广州商城建站在手机上怎么做app软件
- 技术栈
- 2026年04月20日
-
广州市建设工程招标管理办公室网站蓝一互动网站建设
广州市建设工程招标管理办公室网站蓝一互动网站建设
- 技术栈
- 2026年04月20日
-
广州市建设企业网站平台wordpress 电影 插件
广州市建设企业网站平台wordpress 电影 插件
- 技术栈
- 2026年04月20日
-
广州市门户网站建设wordpress阿树
广州市门户网站建设wordpress阿树
- 技术栈
- 2026年04月20日
