main.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <sys/types.h>
  5. #include <sys/wait.h>
  6. #define TEST_ASSERT(left, right, success_msg, fail_msg) \
  7. do { \
  8. if ((left) == (right)) { \
  9. printf("[PASS] %s\n", success_msg); \
  10. } else { \
  11. printf("[FAIL] %s: Expected 0x%lx, but got 0x%lx\n", \
  12. fail_msg, \
  13. (unsigned long)(right), \
  14. (unsigned long)(left)); \
  15. } \
  16. } while (0)
  17. // 打印进程信息
  18. void print_ids(const char *name) {
  19. printf("[%s] PID=%d, PPID=%d, PGID=%d, SID=%d\n",
  20. name,
  21. getpid(),
  22. getppid(),
  23. getpgid(0), // 获取当前进程的 PGID
  24. getsid(0)); // 获取当前进程的 SID
  25. }
  26. int main() {
  27. printf("===== 测试进程组 =====\n");
  28. print_ids("Parent");
  29. // 创建第一个子进程
  30. pid_t child1 = fork();
  31. if (child1 == 0) {
  32. // 子进程1:设置自己的进程组
  33. printf("\n[Child1] 子进程启动...\n");
  34. print_ids("Child1 (before setpgid)");
  35. if (setpgid(0, 0) == -1) { // 将自己的 PGID 设置为自己的 PID
  36. perror("setpgid failed");
  37. exit(EXIT_FAILURE);
  38. }
  39. print_ids("Child1 (after setpgid)");
  40. // Assert: PGID 应该等于 PID
  41. // assert(getpgid(0) == getpid());
  42. TEST_ASSERT(getpgid(0), getpid(), "Successfully set child1 as processgroup leader", "Child1 PGID check failed");
  43. sleep(2); // 保持运行,便于观察
  44. exit(EXIT_SUCCESS);
  45. }
  46. // 创建第二个子进程
  47. pid_t child2 = fork();
  48. if (child2 == 0) {
  49. // 子进程2:加入第一个子进程的进程组
  50. printf("\n[Child2] 子进程启动...\n");
  51. print_ids("Child2 (before setpgid)");
  52. if (setpgid(0, child1) == -1) { // 将自己的 PGID 设置为 child1 的 PID
  53. perror("setpgid failed");
  54. exit(EXIT_FAILURE);
  55. }
  56. print_ids("Child2 (after setpgid)");
  57. // Assert: PGID 应该等于 child1 的 PID
  58. // assert(getpgid(0) == child1);
  59. TEST_ASSERT(getpgid(0),child1,"Child2 PGID is equal to Child1","Child2 PGID check failed");
  60. sleep(2); // 保持运行,便于观察
  61. exit(EXIT_SUCCESS);
  62. }
  63. // 父进程:等待子进程结束
  64. waitpid(child1, NULL, 0);
  65. waitpid(child2, NULL, 0);
  66. printf("\n[Parent] 所有子进程结束后...\n");
  67. print_ids("Parent");
  68. return 0;
  69. }