简体中文 繁體中文 English Deutsch 한국 사람 بالعربية TÜRKÇE português คนไทย Français Japanese

站内搜索

搜索
AI 风月

活动公告

03-01 22:34
通知:本站资源由网友上传分享,如有违规等问题请到版务模块进行投诉,资源失效请在帖子内回复要求补档,会尽快处理!
10-23 09:31

深入浅出Linux高级编程视频教程带你掌握系统调用内存管理进程控制文件操作网络编程多线程开发等核心技能快速提升Linux系统开发能力

3万

主题

602

科技点

3万

积分

白金月票

碾压王

积分
32704

立华奏

发表于 2025-9-20 14:00:00 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
引言

Linux作为开源操作系统的代表,在服务器、嵌入式系统和开发环境中占据着重要地位。掌握Linux高级编程技能对于系统开发人员来说至关重要。本文将深入浅出地介绍Linux高级编程的核心技能,包括系统调用、内存管理、进程控制、文件操作、网络编程和多线程开发,帮助读者快速提升Linux系统开发能力。

系统调用

什么是系统调用

系统调用是用户空间程序与内核空间交互的接口,是操作系统提供给应用程序的服务入口。通过系统调用,应用程序可以请求操作系统执行特权操作,如硬件访问、进程创建、文件操作等。

为什么需要系统调用

系统调用存在的必要性主要体现在以下几个方面:

1. 安全性:防止用户程序直接访问硬件资源,确保系统安全
2. 稳定性:提供统一的接口,避免应用程序直接操作内核
3. 抽象性:简化复杂的硬件操作,提供易于使用的API

常用系统调用及示例
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <fcntl.h>
  5. #include <sys/types.h>
  6. #include <sys/stat.h>
  7. int main() {
  8.     int fd;
  9.     char buffer[1024];
  10.     ssize_t bytes_read;
  11.    
  12.     // 使用open系统调用打开文件
  13.     fd = open("example.txt", O_RDONLY);
  14.     if (fd == -1) {
  15.         perror("open");
  16.         exit(EXIT_FAILURE);
  17.     }
  18.    
  19.     // 使用read系统调用读取文件内容
  20.     bytes_read = read(fd, buffer, sizeof(buffer) - 1);
  21.     if (bytes_read == -1) {
  22.         perror("read");
  23.         close(fd);
  24.         exit(EXIT_FAILURE);
  25.     }
  26.    
  27.     buffer[bytes_read] = '\0'; // 确保字符串以null结尾
  28.     printf("读取的内容: %s\n", buffer);
  29.    
  30.     // 使用close系统调用关闭文件
  31.     if (close(fd) == -1) {
  32.         perror("close");
  33.         exit(EXIT_FAILURE);
  34.     }
  35.    
  36.     return 0;
  37. }
复制代码
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <sys/wait.h>
  5. int main() {
  6.     pid_t pid;
  7.     int status;
  8.    
  9.     // 使用fork系统调用创建子进程
  10.     pid = fork();
  11.    
  12.     if (pid == -1) {
  13.         perror("fork");
  14.         exit(EXIT_FAILURE);
  15.     } else if (pid == 0) {
  16.         // 子进程代码
  17.         printf("子进程: PID = %d, 父进程PID = %d\n", getpid(), getppid());
  18.         // 使用execlp系统调用执行新程序
  19.         execlp("ls", "ls", "-l", NULL);
  20.         // 如果execlp执行成功,下面的代码不会执行
  21.         perror("execlp");
  22.         exit(EXIT_FAILURE);
  23.     } else {
  24.         // 父进程代码
  25.         printf("父进程: PID = %d, 子进程PID = %d\n", getpid(), pid);
  26.         // 使用waitpid系统调用等待子进程结束
  27.         waitpid(pid, &status, 0);
  28.         printf("子进程结束,状态: %d\n", status);
  29.     }
  30.    
  31.     return 0;
  32. }
复制代码

内存管理

Linux内存管理概述

Linux内存管理负责分配和回收内存资源,包括物理内存和虚拟内存。内存管理的核心功能包括:

1. 内存分配:为进程分配所需的内存空间
2. 内存映射:将文件或设备映射到进程地址空间
3. 内存保护:控制内存访问权限
4. 内存共享:允许多个进程共享内存区域

内存分配函数
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. int main() {
  5.     char *buffer;
  6.    
  7.     // 使用malloc分配内存
  8.     buffer = (char *)malloc(1024 * sizeof(char));
  9.     if (buffer == NULL) {
  10.         perror("malloc");
  11.         return EXIT_FAILURE;
  12.     }
  13.    
  14.     strcpy(buffer, "这是使用malloc分配的内存");
  15.     printf("%s\n", buffer);
  16.    
  17.     // 使用free释放内存
  18.     free(buffer);
  19.    
  20.     return 0;
  21. }
复制代码
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <sys/mman.h>
  4. #include <sys/stat.h>
  5. #include <fcntl.h>
  6. #include <unistd.h>
  7. int main() {
  8.     int fd;
  9.     char *mapped;
  10.     struct stat sb;
  11.    
  12.     // 打开文件
  13.     fd = open("example.txt", O_RDONLY);
  14.     if (fd == -1) {
  15.         perror("open");
  16.         return EXIT_FAILURE;
  17.     }
  18.    
  19.     // 获取文件大小
  20.     if (fstat(fd, &sb) == -1) {
  21.         perror("fstat");
  22.         close(fd);
  23.         return EXIT_FAILURE;
  24.     }
  25.    
  26.     // 使用mmap将文件映射到内存
  27.     mapped = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
  28.     if (mapped == MAP_FAILED) {
  29.         perror("mmap");
  30.         close(fd);
  31.         return EXIT_FAILURE;
  32.     }
  33.    
  34.     // 直接访问映射的内存
  35.     printf("文件内容: %.*s\n", (int)sb.st_size, mapped);
  36.    
  37.     // 使用munmap解除映射
  38.     if (munmap(mapped, sb.st_size) == -1) {
  39.         perror("munmap");
  40.     }
  41.    
  42.     close(fd);
  43.    
  44.     return 0;
  45. }
复制代码

内存共享示例
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <sys/mman.h>
  4. #include <sys/wait.h>
  5. #include <unistd.h>
  6. #define SHM_SIZE 1024
  7. int main() {
  8.     int *shared_data;
  9.     pid_t pid;
  10.    
  11.     // 创建共享内存区域
  12.     shared_data = mmap(NULL, SHM_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
  13.     if (shared_data == MAP_FAILED) {
  14.         perror("mmap");
  15.         return EXIT_FAILURE;
  16.     }
  17.    
  18.     // 初始化共享数据
  19.     *shared_data = 0;
  20.    
  21.     // 创建子进程
  22.     pid = fork();
  23.     if (pid == -1) {
  24.         perror("fork");
  25.         munmap(shared_data, SHM_SIZE);
  26.         return EXIT_FAILURE;
  27.     }
  28.    
  29.     if (pid == 0) {
  30.         // 子进程
  31.         printf("子进程: 读取共享数据 = %d\n", *shared_data);
  32.         *shared_data = 42;
  33.         printf("子进程: 修改共享数据为 %d\n", *shared_data);
  34.         exit(EXIT_SUCCESS);
  35.     } else {
  36.         // 父进程
  37.         wait(NULL); // 等待子进程结束
  38.         printf("父进程: 读取共享数据 = %d\n", *shared_data);
  39.     }
  40.    
  41.     // 解除共享内存映射
  42.     if (munmap(shared_data, SHM_SIZE) == -1) {
  43.         perror("munmap");
  44.         return EXIT_FAILURE;
  45.     }
  46.    
  47.     return 0;
  48. }
复制代码

进程控制

进程概念

进程是程序执行的实例,是操作系统进行资源分配和调度的基本单位。每个进程都有独立的地址空间、系统资源和执行状态。

进程创建与终止
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <sys/wait.h>
  5. int main() {
  6.     pid_t pid;
  7.     int status;
  8.    
  9.     // 创建子进程
  10.     pid = fork();
  11.    
  12.     if (pid == -1) {
  13.         perror("fork");
  14.         exit(EXIT_FAILURE);
  15.     } else if (pid == 0) {
  16.         // 子进程
  17.         printf("子进程: PID = %d\n", getpid());
  18.         // 使用execvp执行新程序
  19.         char *args[] = {"echo", "Hello from child process", NULL};
  20.         execvp("echo", args);
  21.         // 如果execvp执行成功,下面的代码不会执行
  22.         perror("execvp");
  23.         exit(EXIT_FAILURE);
  24.     } else {
  25.         // 父进程
  26.         printf("父进程: PID = %d, 子进程PID = %d\n", getpid(), pid);
  27.         // 等待子进程结束
  28.         wait(&status);
  29.         printf("子进程结束,状态: %d\n", WEXITSTATUS(status));
  30.     }
  31.    
  32.     return 0;
  33. }
复制代码

进程间通信
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <sys/wait.h>
  5. int main() {
  6.     int pipefd[2];
  7.     pid_t pid;
  8.     char buffer[1024];
  9.     ssize_t bytes_read;
  10.    
  11.     // 创建管道
  12.     if (pipe(pipefd) == -1) {
  13.         perror("pipe");
  14.         exit(EXIT_FAILURE);
  15.     }
  16.    
  17.     // 创建子进程
  18.     pid = fork();
  19.    
  20.     if (pid == -1) {
  21.         perror("fork");
  22.         close(pipefd[0]);
  23.         close(pipefd[1]);
  24.         exit(EXIT_FAILURE);
  25.     } else if (pid == 0) {
  26.         // 子进程 - 写入数据
  27.         close(pipefd[0]); // 关闭读取端
  28.         
  29.         const char *message = "Hello from child process!";
  30.         write(pipefd[1], message, strlen(message));
  31.         
  32.         close(pipefd[1]);
  33.         exit(EXIT_SUCCESS);
  34.     } else {
  35.         // 父进程 - 读取数据
  36.         close(pipefd[1]); // 关闭写入端
  37.         
  38.         bytes_read = read(pipefd[0], buffer, sizeof(buffer) - 1);
  39.         if (bytes_read == -1) {
  40.             perror("read");
  41.         } else {
  42.             buffer[bytes_read] = '\0';
  43.             printf("父进程接收到: %s\n", buffer);
  44.         }
  45.         
  46.         close(pipefd[0]);
  47.         wait(NULL); // 等待子进程结束
  48.     }
  49.    
  50.     return 0;
  51. }
复制代码
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <sys/ipc.h>
  4. #include <sys/shm.h>
  5. #include <sys/wait.h>
  6. #include <unistd.h>
  7. #define SHM_KEY 1234
  8. #define SHM_SIZE 1024
  9. int main() {
  10.     int shmid;
  11.     char *shared_data;
  12.     pid_t pid;
  13.    
  14.     // 创建共享内存
  15.     shmid = shmget(SHM_KEY, SHM_SIZE, IPC_CREAT | 0666);
  16.     if (shmid == -1) {
  17.         perror("shmget");
  18.         exit(EXIT_FAILURE);
  19.     }
  20.    
  21.     // 将共享内存附加到进程地址空间
  22.     shared_data = (char *)shmat(shmid, NULL, 0);
  23.     if (shared_data == (char *)-1) {
  24.         perror("shmat");
  25.         exit(EXIT_FAILURE);
  26.     }
  27.    
  28.     // 创建子进程
  29.     pid = fork();
  30.     if (pid == -1) {
  31.         perror("fork");
  32.         shmdt(shared_data);
  33.         shmctl(shmid, IPC_RMID, NULL);
  34.         exit(EXIT_FAILURE);
  35.     }
  36.    
  37.     if (pid == 0) {
  38.         // 子进程
  39.         printf("子进程: 写入共享内存\n");
  40.         sprintf(shared_data, "Hello from child process!");
  41.         exit(EXIT_SUCCESS);
  42.     } else {
  43.         // 父进程
  44.         wait(NULL); // 等待子进程结束
  45.         printf("父进程: 从共享内存读取: %s\n", shared_data);
  46.         
  47.         // 分离共享内存
  48.         shmdt(shared_data);
  49.         
  50.         // 删除共享内存
  51.         shmctl(shmid, IPC_RMID, NULL);
  52.     }
  53.    
  54.     return 0;
  55. }
复制代码

文件操作

Linux文件系统概述

Linux文件系统采用树形结构组织文件和目录,所有文件和设备都被视为文件。文件操作是Linux编程中最基本的操作之一。

基本文件操作
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <fcntl.h>
  4. #include <unistd.h>
  5. #include <string.h>
  6. int main() {
  7.     int fd;
  8.     char buffer[1024];
  9.     ssize_t bytes_read;
  10.    
  11.     // 打开文件
  12.     fd = open("example.txt", O_RDONLY);
  13.     if (fd == -1) {
  14.         perror("open");
  15.         return EXIT_FAILURE;
  16.     }
  17.    
  18.     // 读取文件内容
  19.     bytes_read = read(fd, buffer, sizeof(buffer) - 1);
  20.     if (bytes_read == -1) {
  21.         perror("read");
  22.         close(fd);
  23.         return EXIT_FAILURE;
  24.     }
  25.    
  26.     buffer[bytes_read] = '\0'; // 确保字符串以null结尾
  27.     printf("文件内容: %s\n", buffer);
  28.    
  29.     // 关闭文件
  30.     if (close(fd) == -1) {
  31.         perror("close");
  32.         return EXIT_FAILURE;
  33.     }
  34.    
  35.     return 0;
  36. }
复制代码
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <fcntl.h>
  4. #include <unistd.h>
  5. #include <string.h>
  6. int main() {
  7.     int fd;
  8.     const char *message = "Hello, Linux file programming!\n";
  9.     ssize_t bytes_written;
  10.    
  11.     // 打开文件,如果不存在则创建,存在则截断
  12.     fd = open("output.txt", O_WRONLY | O_CREAT | O_TRUNC, 0644);
  13.     if (fd == -1) {
  14.         perror("open");
  15.         return EXIT_FAILURE;
  16.     }
  17.    
  18.     // 写入数据
  19.     bytes_written = write(fd, message, strlen(message));
  20.     if (bytes_written == -1) {
  21.         perror("write");
  22.         close(fd);
  23.         return EXIT_FAILURE);
  24.     }
  25.    
  26.     printf("成功写入 %zd 字节\n", bytes_written);
  27.    
  28.     // 关闭文件
  29.     if (close(fd) == -1) {
  30.         perror("close");
  31.         return EXIT_FAILURE;
  32.     }
  33.    
  34.     return 0;
  35. }
复制代码

文件定位和截断
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <fcntl.h>
  4. #include <unistd.h>
  5. #include <sys/types.h>
  6. int main() {
  7.     int fd;
  8.     off_t offset;
  9.     char buffer[100];
  10.     ssize_t bytes_read;
  11.    
  12.     // 打开文件
  13.     fd = open("example.txt", O_RDWR);
  14.     if (fd == -1) {
  15.         perror("open");
  16.         return EXIT_FAILURE;
  17.     }
  18.    
  19.     // 读取前100个字节
  20.     bytes_read = read(fd, buffer, sizeof(buffer) - 1);
  21.     if (bytes_read == -1) {
  22.         perror("read");
  23.         close(fd);
  24.         return EXIT_FAILURE;
  25.     }
  26.    
  27.     buffer[bytes_read] = '\0';
  28.     printf("读取的内容: %s\n", buffer);
  29.    
  30.     // 定位到文件开头
  31.     offset = lseek(fd, 0, SEEK_SET);
  32.     if (offset == -1) {
  33.         perror("lseek");
  34.         close(fd);
  35.         return EXIT_FAILURE;
  36.     }
  37.    
  38.     // 截断文件到50字节
  39.     if (ftruncate(fd, 50) == -1) {
  40.         perror("ftruncate");
  41.         close(fd);
  42.         return EXIT_FAILURE;
  43.     }
  44.    
  45.     printf("文件已截断为50字节\n");
  46.    
  47.     // 关闭文件
  48.     if (close(fd) == -1) {
  49.         perror("close");
  50.         return EXIT_FAILURE;
  51.     }
  52.    
  53.     return 0;
  54. }
复制代码

目录操作
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <dirent.h>
  4. #include <sys/stat.h>
  5. #include <unistd.h>
  6. void list_directory(const char *path) {
  7.     DIR *dir;
  8.     struct dirent *entry;
  9.     struct stat file_stat;
  10.     char full_path[1024];
  11.    
  12.     // 打开目录
  13.     dir = opendir(path);
  14.     if (dir == NULL) {
  15.         perror("opendir");
  16.         return;
  17.     }
  18.    
  19.     printf("目录 %s 的内容:\n", path);
  20.    
  21.     // 读取目录项
  22.     while ((entry = readdir(dir)) != NULL) {
  23.         // 跳过 "." 和 ".."
  24.         if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
  25.             continue;
  26.         }
  27.         
  28.         // 构建完整路径
  29.         snprintf(full_path, sizeof(full_path), "%s/%s", path, entry->d_name);
  30.         
  31.         // 获取文件状态
  32.         if (stat(full_path, &file_stat) == -1) {
  33.             perror("stat");
  34.             continue;
  35.         }
  36.         
  37.         // 打印文件信息
  38.         printf("%-20s", entry->d_name);
  39.         if (S_ISDIR(file_stat.st_mode)) {
  40.             printf("(目录)\n");
  41.         } else if (S_ISREG(file_stat.st_mode)) {
  42.             printf("(文件, 大小: %ld 字节)\n", file_stat.st_size);
  43.         } else {
  44.             printf("(其他类型)\n");
  45.         }
  46.     }
  47.    
  48.     // 关闭目录
  49.     closedir(dir);
  50. }
  51. int main() {
  52.     const char *path = ".";
  53.     list_directory(path);
  54.     return 0;
  55. }
复制代码

网络编程

网络编程基础

Linux网络编程主要基于Socket API,它提供了一套标准的接口用于网络通信。Socket编程可以分为TCP和UDP两种主要方式。

TCP Socket编程
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <unistd.h>
  5. #include <sys/socket.h>
  6. #include <netinet/in.h>
  7. #include <arpa/inet.h>
  8. #define PORT 8080
  9. #define BUFFER_SIZE 1024
  10. int main() {
  11.     int server_fd, client_fd;
  12.     struct sockaddr_in address;
  13.     int addrlen = sizeof(address);
  14.     char buffer[BUFFER_SIZE] = {0};
  15.     const char *message = "Hello from server";
  16.    
  17.     // 创建socket文件描述符
  18.     if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
  19.         perror("socket failed");
  20.         exit(EXIT_FAILURE);
  21.     }
  22.    
  23.     // 设置socket选项,允许地址重用
  24.     int opt = 1;
  25.     if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) {
  26.         perror("setsockopt");
  27.         exit(EXIT_FAILURE);
  28.     }
  29.    
  30.     address.sin_family = AF_INET;
  31.     address.sin_addr.s_addr = INADDR_ANY;
  32.     address.sin_port = htons(PORT);
  33.    
  34.     // 绑定socket到指定端口
  35.     if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {
  36.         perror("bind failed");
  37.         exit(EXIT_FAILURE);
  38.     }
  39.    
  40.     // 监听连接
  41.     if (listen(server_fd, 3) < 0) {
  42.         perror("listen");
  43.         exit(EXIT_FAILURE);
  44.     }
  45.    
  46.     printf("服务器正在监听端口 %d...\n", PORT);
  47.    
  48.     // 接受连接
  49.     if ((client_fd = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen)) < 0) {
  50.         perror("accept");
  51.         exit(EXIT_FAILURE);
  52.     }
  53.    
  54.     // 读取客户端发送的数据
  55.     ssize_t bytes_read = read(client_fd, buffer, BUFFER_SIZE);
  56.     printf("客户端消息: %s\n", buffer);
  57.    
  58.     // 发送响应给客户端
  59.     send(client_fd, message, strlen(message), 0);
  60.     printf("响应消息已发送\n");
  61.    
  62.     // 关闭socket
  63.     close(client_fd);
  64.     close(server_fd);
  65.    
  66.     return 0;
  67. }
复制代码
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <unistd.h>
  5. #include <sys/socket.h>
  6. #include <netinet/in.h>
  7. #include <arpa/inet.h>
  8. #define PORT 8080
  9. #define BUFFER_SIZE 1024
  10. int main() {
  11.     int sock = 0;
  12.     struct sockaddr_in serv_addr;
  13.     char buffer[BUFFER_SIZE] = {0};
  14.     const char *message = "Hello from client";
  15.    
  16.     // 创建socket文件描述符
  17.     if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
  18.         printf("\n Socket creation error \n");
  19.         return -1;
  20.     }
  21.    
  22.     serv_addr.sin_family = AF_INET;
  23.     serv_addr.sin_port = htons(PORT);
  24.    
  25.     // 将IPv4地址从文本转换为二进制形式
  26.     if (inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr) <= 0) {
  27.         printf("\nInvalid address/ Address not supported \n");
  28.         return -1;
  29.     }
  30.    
  31.     // 连接到服务器
  32.     if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
  33.         printf("\nConnection Failed \n");
  34.         return -1;
  35.     }
  36.    
  37.     // 发送消息到服务器
  38.     send(sock, message, strlen(message), 0);
  39.     printf("消息已发送\n");
  40.    
  41.     // 读取服务器响应
  42.     ssize_t bytes_read = read(sock, buffer, BUFFER_SIZE);
  43.     printf("服务器响应: %s\n", buffer);
  44.    
  45.     // 关闭socket
  46.     close(sock);
  47.    
  48.     return 0;
  49. }
复制代码

UDP Socket编程
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <unistd.h>
  5. #include <sys/socket.h>
  6. #include <netinet/in.h>
  7. #include <arpa/inet.h>
  8. #define PORT 8080
  9. #define BUFFER_SIZE 1024
  10. int main() {
  11.     int sockfd;
  12.     char buffer[BUFFER_SIZE];
  13.     struct sockaddr_in servaddr, cliaddr;
  14.    
  15.     // 创建socket文件描述符
  16.     if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
  17.         perror("socket creation failed");
  18.         exit(EXIT_FAILURE);
  19.     }
  20.    
  21.     memset(&servaddr, 0, sizeof(servaddr));
  22.     memset(&cliaddr, 0, sizeof(cliaddr));
  23.    
  24.     // 填充服务器信息
  25.     servaddr.sin_family = AF_INET;
  26.     servaddr.sin_addr.s_addr = INADDR_ANY;
  27.     servaddr.sin_port = htons(PORT);
  28.    
  29.     // 绑定socket到指定端口
  30.     if (bind(sockfd, (const struct sockaddr *)&servaddr, sizeof(servaddr)) < 0) {
  31.         perror("bind failed");
  32.         exit(EXIT_FAILURE);
  33.     }
  34.    
  35.     printf("UDP服务器正在监听端口 %d...\n", PORT);
  36.    
  37.     int len, n;
  38.     len = sizeof(cliaddr);
  39.    
  40.     // 接收客户端消息
  41.     n = recvfrom(sockfd, (char *)buffer, BUFFER_SIZE, MSG_WAITALL, (struct sockaddr *)&cliaddr, &len);
  42.     buffer[n] = '\0';
  43.     printf("客户端消息: %s\n", buffer);
  44.    
  45.     // 发送响应给客户端
  46.     const char *response = "Hello from UDP server";
  47.     sendto(sockfd, (const char *)response, strlen(response), MSG_CONFIRM, (const struct sockaddr *)&cliaddr, len);
  48.     printf("响应消息已发送\n");
  49.    
  50.     // 关闭socket
  51.     close(sockfd);
  52.    
  53.     return 0;
  54. }
复制代码
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <unistd.h>
  5. #include <sys/socket.h>
  6. #include <netinet/in.h>
  7. #include <arpa/inet.h>
  8. #define PORT 8080
  9. #define BUFFER_SIZE 1024
  10. int main() {
  11.     int sockfd;
  12.     char buffer[BUFFER_SIZE];
  13.     struct sockaddr_in servaddr;
  14.    
  15.     // 创建socket文件描述符
  16.     if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
  17.         perror("socket creation failed");
  18.         exit(EXIT_FAILURE);
  19.     }
  20.    
  21.     memset(&servaddr, 0, sizeof(servaddr));
  22.    
  23.     // 填充服务器信息
  24.     servaddr.sin_family = AF_INET;
  25.     servaddr.sin_port = htons(PORT);
  26.     servaddr.sin_addr.s_addr = INADDR_ANY;
  27.    
  28.     // 将IPv4地址从文本转换为二进制形式
  29.     inet_pton(AF_INET, "127.0.0.1", &servaddr.sin_addr);
  30.    
  31.     const char *message = "Hello from UDP client";
  32.    
  33.     // 发送消息到服务器
  34.     sendto(sockfd, (const char *)message, strlen(message), MSG_CONFIRM, (const struct sockaddr *)&servaddr, sizeof(servaddr));
  35.     printf("消息已发送\n");
  36.    
  37.     // 接收服务器响应
  38.     int n, len;
  39.     len = sizeof(servaddr);
  40.     n = recvfrom(sockfd, (char *)buffer, BUFFER_SIZE, MSG_WAITALL, (struct sockaddr *)&servaddr, &len);
  41.     buffer[n] = '\0';
  42.     printf("服务器响应: %s\n", buffer);
  43.    
  44.     // 关闭socket
  45.     close(sockfd);
  46.    
  47.     return 0;
  48. }
复制代码

多线程开发

线程概念

线程是进程内的执行单元,共享进程的资源。多线程编程可以提高程序的并发性和响应性,特别适合I/O密集型任务。

POSIX线程(Pthreads)
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <pthread.h>
  4. #define NUM_THREADS 5
  5. // 线程函数
  6. void *thread_function(void *arg) {
  7.     int thread_id = *((int *)arg);
  8.     printf("线程 %d: 正在运行\n", thread_id);
  9.    
  10.     // 模拟工作
  11.     for (int i = 0; i < 3; i++) {
  12.         printf("线程 %d: 工作中... %d\n", thread_id, i);
  13.         sleep(1);
  14.     }
  15.    
  16.     printf("线程 %d: 完成\n", thread_id);
  17.     pthread_exit(NULL);
  18. }
  19. int main() {
  20.     pthread_t threads[NUM_THREADS];
  21.     int thread_args[NUM_THREADS];
  22.     int rc;
  23.    
  24.     // 创建线程
  25.     for (int i = 0; i < NUM_THREADS; i++) {
  26.         thread_args[i] = i;
  27.         printf("主线程: 创建线程 %d\n", i);
  28.         
  29.         rc = pthread_create(&threads[i], NULL, thread_function, &thread_args[i]);
  30.         if (rc) {
  31.             printf("错误: 无法创建线程 %d, 错误码: %d\n", i, rc);
  32.             exit(EXIT_FAILURE);
  33.         }
  34.     }
  35.    
  36.     // 等待所有线程完成
  37.     for (int i = 0; i < NUM_THREADS; i++) {
  38.         rc = pthread_join(threads[i], NULL);
  39.         if (rc) {
  40.             printf("错误: 无法加入线程 %d, 错误码: %d\n", i, rc);
  41.             exit(EXIT_FAILURE);
  42.         }
  43.         printf("主线程: 线程 %d 已完成\n", i);
  44.     }
  45.    
  46.     printf("主线程: 所有线程已完成\n");
  47.     pthread_exit(NULL);
  48.    
  49.     return 0;
  50. }
复制代码

线程同步
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <pthread.h>
  4. #define NUM_THREADS 5
  5. #define ITERATIONS 1000000
  6. int counter = 0;
  7. pthread_mutex_t mutex;
  8. // 线程函数
  9. void *thread_function(void *arg) {
  10.     int thread_id = *((int *)arg);
  11.    
  12.     for (int i = 0; i < ITERATIONS; i++) {
  13.         // 锁定互斥量
  14.         pthread_mutex_lock(&mutex);
  15.         
  16.         // 临界区 - 访问共享资源
  17.         counter++;
  18.         
  19.         // 解锁互斥量
  20.         pthread_mutex_unlock(&mutex);
  21.     }
  22.    
  23.     printf("线程 %d: 完成\n", thread_id);
  24.     pthread_exit(NULL);
  25. }
  26. int main() {
  27.     pthread_t threads[NUM_THREADS];
  28.     int thread_args[NUM_THREADS];
  29.     int rc;
  30.    
  31.     // 初始化互斥量
  32.     pthread_mutex_init(&mutex, NULL);
  33.    
  34.     // 创建线程
  35.     for (int i = 0; i < NUM_THREADS; i++) {
  36.         thread_args[i] = i;
  37.         printf("主线程: 创建线程 %d\n", i);
  38.         
  39.         rc = pthread_create(&threads[i], NULL, thread_function, &thread_args[i]);
  40.         if (rc) {
  41.             printf("错误: 无法创建线程 %d, 错误码: %d\n", i, rc);
  42.             exit(EXIT_FAILURE);
  43.         }
  44.     }
  45.    
  46.     // 等待所有线程完成
  47.     for (int i = 0; i < NUM_THREADS; i++) {
  48.         rc = pthread_join(threads[i], NULL);
  49.         if (rc) {
  50.             printf("错误: 无法加入线程 %d, 错误码: %d\n", i, rc);
  51.             exit(EXIT_FAILURE);
  52.         }
  53.     }
  54.    
  55.     // 销毁互斥量
  56.     pthread_mutex_destroy(&mutex);
  57.    
  58.     printf("主线程: 所有线程已完成\n");
  59.     printf("最终计数器值: %d (预期值: %d)\n", counter, NUM_THREADS * ITERATIONS);
  60.    
  61.     return 0;
  62. }
复制代码
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <pthread.h>
  4. #define BUFFER_SIZE 10
  5. #define NUM_ITEMS 20
  6. int buffer[BUFFER_SIZE];
  7. int count = 0;
  8. int in = 0;
  9. int out = 0;
  10. pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
  11. pthread_cond_t cond_producer = PTHREAD_COND_INITIALIZER;
  12. pthread_cond_t cond_consumer = PTHREAD_COND_INITIALIZER;
  13. // 生产者函数
  14. void *producer(void *arg) {
  15.     int producer_id = *((int *)arg);
  16.     int item;
  17.    
  18.     for (int i = 0; i < NUM_ITEMS; i++) {
  19.         item = producer_id * 100 + i; // 生成项目
  20.         
  21.         // 锁定互斥量
  22.         pthread_mutex_lock(&mutex);
  23.         
  24.         // 如果缓冲区满,等待消费者消费
  25.         while (count == BUFFER_SIZE) {
  26.             printf("生产者 %d: 缓冲区满,等待...\n", producer_id);
  27.             pthread_cond_wait(&cond_producer, &mutex);
  28.         }
  29.         
  30.         // 生产项目
  31.         buffer[in] = item;
  32.         in = (in + 1) % BUFFER_SIZE;
  33.         count++;
  34.         
  35.         printf("生产者 %d: 生产项目 %d\n", producer_id, item);
  36.         
  37.         // 通知消费者有新项目
  38.         pthread_cond_signal(&cond_consumer);
  39.         
  40.         // 解锁互斥量
  41.         pthread_mutex_unlock(&mutex);
  42.         
  43.         // 模拟生产时间
  44.         usleep(100000); // 100毫秒
  45.     }
  46.    
  47.     printf("生产者 %d: 完成\n", producer_id);
  48.     pthread_exit(NULL);
  49. }
  50. // 消费者函数
  51. void *consumer(void *arg) {
  52.     int consumer_id = *((int *)arg);
  53.     int item;
  54.    
  55.     for (int i = 0; i < NUM_ITEMS; i++) {
  56.         // 锁定互斥量
  57.         pthread_mutex_lock(&mutex);
  58.         
  59.         // 如果缓冲区空,等待生产者生产
  60.         while (count == 0) {
  61.             printf("消费者 %d: 缓冲区空,等待...\n", consumer_id);
  62.             pthread_cond_wait(&cond_consumer, &mutex);
  63.         }
  64.         
  65.         // 消费项目
  66.         item = buffer[out];
  67.         out = (out + 1) % BUFFER_SIZE;
  68.         count--;
  69.         
  70.         printf("消费者 %d: 消费项目 %d\n", consumer_id, item);
  71.         
  72.         // 通知生产者有空间
  73.         pthread_cond_signal(&cond_producer);
  74.         
  75.         // 解锁互斥量
  76.         pthread_mutex_unlock(&mutex);
  77.         
  78.         // 模拟消费时间
  79.         usleep(200000); // 200毫秒
  80.     }
  81.    
  82.     printf("消费者 %d: 完成\n", consumer_id);
  83.     pthread_exit(NULL);
  84. }
  85. int main() {
  86.     pthread_t producers[2];
  87.     pthread_t consumers[2];
  88.     int producer_ids[2] = {1, 2};
  89.     int consumer_ids[2] = {1, 2};
  90.     int rc;
  91.    
  92.     // 创建生产者线程
  93.     for (int i = 0; i < 2; i++) {
  94.         rc = pthread_create(&producers[i], NULL, producer, &producer_ids[i]);
  95.         if (rc) {
  96.             printf("错误: 无法创建生产者线程 %d, 错误码: %d\n", i, rc);
  97.             exit(EXIT_FAILURE);
  98.         }
  99.     }
  100.    
  101.     // 创建消费者线程
  102.     for (int i = 0; i < 2; i++) {
  103.         rc = pthread_create(&consumers[i], NULL, consumer, &consumer_ids[i]);
  104.         if (rc) {
  105.             printf("错误: 无法创建消费者线程 %d, 错误码: %d\n", i, rc);
  106.             exit(EXIT_FAILURE);
  107.         }
  108.     }
  109.    
  110.     // 等待所有线程完成
  111.     for (int i = 0; i < 2; i++) {
  112.         pthread_join(producers[i], NULL);
  113.         pthread_join(consumers[i], NULL);
  114.     }
  115.    
  116.     // 销毁互斥量和条件变量
  117.     pthread_mutex_destroy(&mutex);
  118.     pthread_cond_destroy(&cond_producer);
  119.     pthread_cond_destroy(&cond_consumer);
  120.    
  121.     printf("主线程: 所有线程已完成\n");
  122.    
  123.     return 0;
  124. }
复制代码

实践案例:多线程Web服务器

下面是一个结合了前面介绍的多项技术的综合案例:一个简单的多线程Web服务器。
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <unistd.h>
  5. #include <sys/socket.h>
  6. #include <netinet/in.h>
  7. #include <arpa/inet.h>
  8. #include <pthread.h>
  9. #include <sys/stat.h>
  10. #include <fcntl.h>
  11. #define PORT 8080
  12. #define BUFFER_SIZE 4096
  13. #define THREAD_POOL_SIZE 10
  14. // 线程池结构
  15. typedef struct {
  16.     pthread_t *threads;
  17.     int thread_count;
  18.     int queue_size;
  19.     int front;
  20.     int rear;
  21.     int count;
  22.     int *client_fds;
  23.     pthread_mutex_t lock;
  24.     pthread_cond_t notify;
  25.     int shutdown;
  26. } thread_pool_t;
  27. // HTTP请求结构
  28. typedef struct {
  29.     int client_fd;
  30.     struct sockaddr_in client_addr;
  31. } http_request_t;
  32. // 初始化线程池
  33. thread_pool_t *thread_pool_create(int thread_count, int queue_size) {
  34.     thread_pool_t *pool = (thread_pool_t *)malloc(sizeof(thread_pool_t));
  35.     if (pool == NULL) {
  36.         perror("malloc");
  37.         return NULL;
  38.     }
  39.    
  40.     pool->thread_count = thread_count;
  41.     pool->queue_size = queue_size;
  42.     pool->front = 0;
  43.     pool->rear = 0;
  44.     pool->count = 0;
  45.     pool->shutdown = 0;
  46.    
  47.     // 初始化互斥量和条件变量
  48.     pthread_mutex_init(&(pool->lock), NULL);
  49.     pthread_cond_init(&(pool->notify), NULL);
  50.    
  51.     // 分配线程数组
  52.     pool->threads = (pthread_t *)malloc(sizeof(pthread_t) * thread_count);
  53.     if (pool->threads == NULL) {
  54.         perror("malloc");
  55.         free(pool);
  56.         return NULL;
  57.     }
  58.    
  59.     // 分配客户端文件描述符数组
  60.     pool->client_fds = (int *)malloc(sizeof(int) * queue_size);
  61.     if (pool->client_fds == NULL) {
  62.         perror("malloc");
  63.         free(pool->threads);
  64.         free(pool);
  65.         return NULL;
  66.     }
  67.    
  68.     // 创建工作线程
  69.     for (int i = 0; i < thread_count; i++) {
  70.         if (pthread_create(&(pool->threads[i]), NULL, thread_pool_worker, (void *)pool) != 0) {
  71.             perror("pthread_create");
  72.             free(pool->threads);
  73.             free(pool->client_fds);
  74.             free(pool);
  75.             return NULL;
  76.         }
  77.     }
  78.    
  79.     return pool;
  80. }
  81. // 工作线程函数
  82. void *thread_pool_worker(void *arg) {
  83.     thread_pool_t *pool = (thread_pool_t *)arg;
  84.     int client_fd;
  85.    
  86.     while (1) {
  87.         // 锁定互斥量
  88.         pthread_mutex_lock(&(pool->lock));
  89.         
  90.         // 等待任务或关闭信号
  91.         while (pool->count == 0 && !pool->shutdown) {
  92.             pthread_cond_wait(&(pool->notify), &(pool->lock));
  93.         }
  94.         
  95.         // 如果线程池关闭且没有任务,退出线程
  96.         if (pool->shutdown && pool->count == 0) {
  97.             pthread_mutex_unlock(&(pool->lock));
  98.             pthread_exit(NULL);
  99.         }
  100.         
  101.         // 获取客户端文件描述符
  102.         client_fd = pool->client_fds[pool->front];
  103.         pool->front = (pool->front + 1) % pool->queue_size;
  104.         pool->count--;
  105.         
  106.         // 解锁互斥量
  107.         pthread_mutex_unlock(&(pool->lock));
  108.         
  109.         // 处理HTTP请求
  110.         handle_http_request(client_fd);
  111.         
  112.         // 关闭客户端连接
  113.         close(client_fd);
  114.     }
  115.    
  116.     pthread_exit(NULL);
  117.     return NULL;
  118. }
  119. // 添加任务到线程池
  120. int thread_pool_add_task(thread_pool_t *pool, int client_fd) {
  121.     int err = 0;
  122.    
  123.     // 锁定互斥量
  124.     pthread_mutex_lock(&(pool->lock));
  125.    
  126.     // 检查队列是否已满
  127.     if (pool->count == pool->queue_size) {
  128.         err = -1;
  129.     } else {
  130.         // 添加客户端文件描述符到队列
  131.         pool->client_fds[pool->rear] = client_fd;
  132.         pool->rear = (pool->rear + 1) % pool->queue_size;
  133.         pool->count++;
  134.         
  135.         // 通知工作线程有新任务
  136.         pthread_cond_signal(&(pool->notify));
  137.     }
  138.    
  139.     // 解锁互斥量
  140.     pthread_mutex_unlock(&(pool->lock));
  141.    
  142.     return err;
  143. }
  144. // 销毁线程池
  145. void thread_pool_destroy(thread_pool_t *pool) {
  146.     if (pool == NULL) {
  147.         return;
  148.     }
  149.    
  150.     // 锁定互斥量
  151.     pthread_mutex_lock(&(pool->lock));
  152.    
  153.     // 设置关闭标志
  154.     pool->shutdown = 1;
  155.    
  156.     // 解锁互斥量
  157.     pthread_mutex_unlock(&(pool->lock));
  158.    
  159.     // 通知所有工作线程
  160.     pthread_cond_broadcast(&(pool->notify));
  161.    
  162.     // 等待所有工作线程结束
  163.     for (int i = 0; i < pool->thread_count; i++) {
  164.         pthread_join(pool->threads[i], NULL);
  165.     }
  166.    
  167.     // 销毁互斥量和条件变量
  168.     pthread_mutex_destroy(&(pool->lock));
  169.     pthread_cond_destroy(&(pool->notify));
  170.    
  171.     // 释放内存
  172.     free(pool->threads);
  173.     free(pool->client_fds);
  174.     free(pool);
  175. }
  176. // 处理HTTP请求
  177. void handle_http_request(int client_fd) {
  178.     char buffer[BUFFER_SIZE];
  179.     ssize_t bytes_read;
  180.    
  181.     // 读取HTTP请求
  182.     bytes_read = read(client_fd, buffer, BUFFER_SIZE - 1);
  183.     if (bytes_read <= 0) {
  184.         return;
  185.     }
  186.    
  187.     buffer[bytes_read] = '\0';
  188.     printf("收到请求:\n%s\n", buffer);
  189.    
  190.     // 解析请求方法
  191.     char method[16];
  192.     char path[256];
  193.     sscanf(buffer, "%15s %255s", method, path);
  194.    
  195.     // 处理GET请求
  196.     if (strcmp(method, "GET") == 0) {
  197.         // 默认页面
  198.         if (strcmp(path, "/") == 0) {
  199.             strcpy(path, "/index.html");
  200.         }
  201.         
  202.         // 构建文件路径
  203.         char file_path[512];
  204.         snprintf(file_path, sizeof(file_path), "public%s", path);
  205.         
  206.         // 检查文件是否存在
  207.         struct stat file_stat;
  208.         if (stat(file_path, &file_stat) == -1) {
  209.             // 文件不存在,返回404
  210.             send_http_response(client_fd, 404, "Not Found", "text/html", "<html><body><h1>404 Not Found</h1></body></html>");
  211.             return;
  212.         }
  213.         
  214.         // 如果是目录,尝试查找index.html
  215.         if (S_ISDIR(file_stat.st_mode)) {
  216.             strcat(file_path, "/index.html");
  217.             if (stat(file_path, &file_stat) == -1) {
  218.                 send_http_response(client_fd, 404, "Not Found", "text/html", "<html><body><h1>404 Not Found</h1></body></html>");
  219.                 return;
  220.             }
  221.         }
  222.         
  223.         // 读取文件内容
  224.         int file_fd = open(file_path, O_RDONLY);
  225.         if (file_fd == -1) {
  226.             send_http_response(client_fd, 500, "Internal Server Error", "text/html", "<html><body><h1>500 Internal Server Error</h1></body></html>");
  227.             return;
  228.         }
  229.         
  230.         // 确定MIME类型
  231.         const char *mime_type = "text/plain";
  232.         if (strstr(file_path, ".html") != NULL) {
  233.             mime_type = "text/html";
  234.         } else if (strstr(file_path, ".css") != NULL) {
  235.             mime_type = "text/css";
  236.         } else if (strstr(file_path, ".js") != NULL) {
  237.             mime_type = "application/javascript";
  238.         } else if (strstr(file_path, ".jpg") != NULL || strstr(file_path, ".jpeg") != NULL) {
  239.             mime_type = "image/jpeg";
  240.         } else if (strstr(file_path, ".png") != NULL) {
  241.             mime_type = "image/png";
  242.         } else if (strstr(file_path, ".gif") != NULL) {
  243.             mime_type = "image/gif";
  244.         }
  245.         
  246.         // 发送HTTP响应头
  247.         char header[BUFFER_SIZE];
  248.         snprintf(header, sizeof(header),
  249.                  "HTTP/1.1 200 OK\r\n"
  250.                  "Content-Type: %s\r\n"
  251.                  "Content-Length: %ld\r\n"
  252.                  "\r\n",
  253.                  mime_type, file_stat.st_size);
  254.         
  255.         write(client_fd, header, strlen(header));
  256.         
  257.         // 发送文件内容
  258.         char file_buffer[BUFFER_SIZE];
  259.         ssize_t bytes_read;
  260.         while ((bytes_read = read(file_fd, file_buffer, BUFFER_SIZE)) > 0) {
  261.             write(client_fd, file_buffer, bytes_read);
  262.         }
  263.         
  264.         close(file_fd);
  265.     } else {
  266.         // 不支持的HTTP方法
  267.         send_http_response(client_fd, 405, "Method Not Allowed", "text/html", "<html><body><h1>405 Method Not Allowed</h1></body></html>");
  268.     }
  269. }
  270. // 发送HTTP响应
  271. void send_http_response(int client_fd, int status_code, const char *status_text, const char *content_type, const char *content) {
  272.     char response[BUFFER_SIZE];
  273.     snprintf(response, sizeof(response),
  274.              "HTTP/1.1 %d %s\r\n"
  275.              "Content-Type: %s\r\n"
  276.              "Content-Length: %ld\r\n"
  277.              "\r\n"
  278.              "%s",
  279.              status_code, status_text, content_type, strlen(content), content);
  280.    
  281.     write(client_fd, response, strlen(response));
  282. }
  283. int main() {
  284.     int server_fd, client_fd;
  285.     struct sockaddr_in address;
  286.     int addrlen = sizeof(address);
  287.    
  288.     // 创建线程池
  289.     thread_pool_t *pool = thread_pool_create(THREAD_POOL_SIZE, 100);
  290.     if (pool == NULL) {
  291.         fprintf(stderr, "无法创建线程池\n");
  292.         return EXIT_FAILURE;
  293.     }
  294.    
  295.     // 创建socket文件描述符
  296.     if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
  297.         perror("socket failed");
  298.         thread_pool_destroy(pool);
  299.         return EXIT_FAILURE;
  300.     }
  301.    
  302.     // 设置socket选项,允许地址重用
  303.     int opt = 1;
  304.     if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) {
  305.         perror("setsockopt");
  306.         thread_pool_destroy(pool);
  307.         return EXIT_FAILURE;
  308.     }
  309.    
  310.     address.sin_family = AF_INET;
  311.     address.sin_addr.s_addr = INADDR_ANY;
  312.     address.sin_port = htons(PORT);
  313.    
  314.     // 绑定socket到指定端口
  315.     if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {
  316.         perror("bind failed");
  317.         thread_pool_destroy(pool);
  318.         return EXIT_FAILURE;
  319.     }
  320.    
  321.     // 监听连接
  322.     if (listen(server_fd, 10) < 0) {
  323.         perror("listen");
  324.         thread_pool_destroy(pool);
  325.         return EXIT_FAILURE;
  326.     }
  327.    
  328.     printf("服务器正在监听端口 %d...\n", PORT);
  329.    
  330.     // 主循环:接受连接并添加到线程池
  331.     while (1) {
  332.         // 接受连接
  333.         if ((client_fd = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen)) < 0) {
  334.             perror("accept");
  335.             continue;
  336.         }
  337.         
  338.         printf("新连接: %s:%d\n", inet_ntoa(address.sin_addr), ntohs(address.sin_port));
  339.         
  340.         // 添加任务到线程池
  341.         if (thread_pool_add_task(pool, client_fd) != 0) {
  342.             fprintf(stderr, "线程池队列已满,拒绝连接\n");
  343.             close(client_fd);
  344.         }
  345.     }
  346.    
  347.     // 销毁线程池
  348.     thread_pool_destroy(pool);
  349.    
  350.     // 关闭服务器socket
  351.     close(server_fd);
  352.    
  353.     return 0;
  354. }
复制代码

这个多线程Web服务器结合了前面介绍的多种技术:

1. 网络编程:使用Socket API处理网络连接
2. 多线程开发:使用线程池处理并发请求
3. 文件操作:读取和发送静态文件
4. 进程控制:虽然是多线程,但也涉及并发概念
5. 系统调用:使用各种系统调用进行I/O操作

学习资源推荐

书籍

1. 《Linux/UNIX系统编程手册》(The Linux Programming Interface) - Michael Kerrisk
2. 《UNIX环境高级编程》(Advanced Programming in the UNIX Environment) - W. Richard Stevens
3. 《Linux多线程服务端编程》 - 陈硕
4. 《TCP/IP详解 卷一:协议》 - W. Richard Stevens

在线资源

1. Linux手册页 (man pages)
2. Linux内核文档 (https://www.kernel.org/doc/)
3. GNU C库参考手册 (https://www.gnu.org/software/libc/manual/)
4. Linux Foundation培训课程 (https://training.linuxfoundation.org/)

实践项目

1. 实现一个简单的Shell
2. 开发一个网络聊天室
3. 编写一个多线程文件服务器
4. 实现一个简单的数据库系统
5. 开发一个Web服务器

总结

Linux高级编程是系统开发的核心技能,涉及系统调用、内存管理、进程控制、文件操作、网络编程和多线程开发等多个方面。通过深入理解这些概念和技术,并结合实际项目进行实践,可以快速提升Linux系统开发能力。

本文详细介绍了Linux高级编程的各个方面,并提供了丰富的代码示例,帮助读者理解和应用这些技术。希望读者能够通过学习和实践,掌握Linux高级编程的核心技能,成为一名优秀的Linux系统开发人员。

记住,编程技能的提升需要不断的学习和实践。继续探索Linux系统的奥秘,挑战更复杂的项目,你的Linux系统开发能力将不断提升。
「七転び八起き(ななころびやおき)」
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

站长推荐上一条 /1 下一条

手机版|联系我们|小黑屋|TG频道|RSS |网站地图

Powered by Pixtech

© 2025-2026 Pixtech Team.

>