1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
| #define _GNU_SOURCE #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h> #include <errno.h> #include <string.h>
// 信号量操作联合体(某些系统需要) union semun { int val; // 用于SETVAL struct semid_ds *buf; // 用于IPC_STAT和IPC_SET unsigned short *array; // 用于GETALL和SETALL };
int main() { key_t key; int semid; printf("=== Semget函数示例 ===\n"); // 示例1: 使用IPC_PRIVATE创建私有信号量集 printf("\n示例1: 创建私有信号量集\n"); semid = semget(IPC_PRIVATE, 1, 0666 | IPC_CREAT); if (semid == -1) { perror("semget IPC_PRIVATE失败"); exit(EXIT_FAILURE); } printf(" 成功创建私有信号量集,标识符: %d\n", semid); // 删除信号量集 if (semctl(semid, 0, IPC_RMID) == -1) { perror("删除信号量集失败"); } else { printf(" 成功删除信号量集\n"); } // 示例2: 使用ftok生成键值创建信号量集 printf("\n示例2: 使用ftok创建信号量集\n"); // 生成键值(基于当前文件和项目ID) key = ftok(".", 'a'); if (key == -1) { perror("ftok失败"); exit(EXIT_FAILURE); } printf(" 生成的键值: %d\n", key); // 创建信号量集(包含3个信号量) semid = semget(key, 3, 0666 | IPC_CREAT); if (semid == -1) { perror("semget创建失败"); exit(EXIT_FAILURE); } printf(" 成功创建信号量集,标识符: %d\n", semid); // 示例3: 尝试创建已存在的信号量集 printf("\n示例3: 尝试重复创建信号量集\n"); int semid2 = semget(key, 3, 0666 | IPC_CREAT | IPC_EXCL); if (semid2 == -1) { if (errno == EEXIST) { printf(" 信号量集已存在\n"); } else { perror(" semget失败"); } } else { printf(" 意外创建了新的信号量集: %d\n", semid2); } // 示例4: 获取已存在的信号量集 printf("\n示例4: 获取已存在的信号量集\n"); int semid3 = semget(key, 0, 0666); if (semid3 == -1) { perror("获取信号量集失败"); } else { printf(" 成功获取信号量集,标识符: %d\n", semid3); // 验证是否为同一个信号量集 if (semid3 == semid) { printf(" 确认为同一个信号量集\n"); } } // 示例5: 错误处理演示 printf("\n示例5: 错误处理\n"); // 尝试访问不存在的信号量集(不创建) int semid4 = semget(12345, 1, 0666); if (semid4 == -1) { if (errno == ENOENT) { printf(" 信号量集不存在: %s\n", strerror(errno)); } else { perror(" 其他错误"); } } // 清理:删除创建的信号量集 printf("\n清理资源...\n"); if (semctl(semid, 0, IPC_RMID) == -1) { perror("清理信号量集失败"); } else { printf(" 成功清理信号量集\n"); } return 0; }
|