Skip to content

Ch 10: 系统与进程

  • 处理文件系统操作
  • 调用外部进程
  • 管理环境变量
  • 理解线程基础

os 模块提供操作系统交互接口:

import os
# 环境变量
home = os.environ["HOME"]
path = os.getenv("PATH", "")
os.putenv("VAR", "value")
# 命令行参数
import sys
sys.argv # [程序名, arg1, arg2, ...]
# 目录操作
os.getcwd() # 当前目录
os.chdir("/tmp") # 切换目录
os.mkdir("dir") # 创建目录
os.makedirs("a/b/c") # 递归创建
os.rmdir("dir") # 删除空目录
os.remove("file.txt") # 删除文件
os.rename("old", "new") # 重命名
# 文件信息
os.path.exists("file.txt")
os.path.isfile("file.txt")
os.path.isdir("path")
os.path.getsize("file.txt")
os.path.join("dir", "file.txt")
os.path.split("/a/b.txt") # ('/a', 'b.txt')
# 目录内容
os.listdir(".")
os.scandir(".") # 更高效的迭代器
# 文件权限
os.chmod("file.txt", 0o755)
os.access("file.txt", os.R_OK | os.W_OK)
#include <filesystem>
#include <cstdlib>
#include <iostream>
namespace fs = std::filesystem;
// 环境变量
const char* home = std::getenv("HOME");
const char* path = std::getenv("PATH");
std::setenv("VAR", "value", 1); // 1 = overwrite
// main 函数参数
int main(int argc, char* argv[]) {
for (int i = 0; i < argc; ++i) {
std::cout << argv[i] << std::endl;
}
}
// 目录操作
fs::current_path(); // 当前目录
fs::current_path(fs::path("/tmp")); // 切换
fs::create_directory("dir"); // 创建目录
fs::create_directories("a/b/c"); // 递归创建
fs::remove("dir"); // 删除空目录
fs::remove("file.txt"); // 删除文件
fs::rename("old", "new"); // 重命名
// 文件信息
fs::exists("file.txt");
fs::is_regular_file("file.txt");
fs::is_directory("path");
fs::file_size("file.txt");
fs::path p = "dir" / "file.txt"; // 路径拼接
// 目录内容
for (const auto& entry : fs::directory_iterator(".")) {
std::cout << entry.path() << std::endl;
}
// 文件权限(C++20)
fs::permissions("file.txt", fs::perms::owner_read | fs::perms::owner_write);

subprocess 用于执行外部命令:

import subprocess
# 执行命令(等待完成)
result = subprocess.run(
["ls", "-la"],
capture_output=True, # 捕获输出
text=True # 返回字符串
)
print(result.stdout)
print(result.stderr)
print(result.returncode) # 退出码
# 检查返回码
if result.returncode != 0:
print(f"Error: {result.stderr}")
# shell=True(注意安全)
result = subprocess.run("ls -la | grep txt", shell=True)
# 捕获输出但不等待
proc = subprocess.Popen(
["python", "script.py"],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
)
stdout, stderr = proc.communicate()
# 发送信号
proc.terminate() # SIGTERM
proc.kill() # SIGKILL
# 超时
result = subprocess.run(
["sleep", "10"],
timeout=5 # 5 秒超时
)
#include <cstdlib>
#include <iostream>
int main() {
// 简单调用
int result = std::system("ls -la");
// 检查返回码
if (result != 0) {
std::cerr << "Command failed" << std::endl;
}
return 0;
}

C++20 引入了 std::process:

#include <processes>
#include <iostream>
int main() {
// 运行命令
auto result = std::process::system("ls -la");
// 异步执行(C++20)
auto child = std::process::spawn("python", {"script.py"});
// 等待完成
auto exit_status = child.wait();
std::cout << "Exit code: " << exit_status << std::endl;
// 注意:std::process 是 C++20 标准库扩展
// 很多编译器尚未完全支持
return 0;
}
#include <cstdio>
#include <iostream>
int main() {
// 读取命令输出
FILE* fp = std::popen("ls -la", "r");
if (fp) {
char buf[256];
while (std::fgets(buf, sizeof(buf), fp) != nullptr) {
std::cout << buf;
}
std::pclose(fp);
}
return 0;
}
import threading
# 创建线程
def worker(n):
print(f"Thread {n} started")
t = threading.Thread(target=worker, args=(1,))
t.start()
t.join()
# 带返回值
def worker_with_return(n):
return n * 2
with concurrent.futures.ThreadPoolExecutor() as executor:
future = executor.submit(worker_with_return, 5)
result = future.result() # 10
# 锁
lock = threading.Lock()
with lock:
# 临界区
pass
# 事件
event = threading.Event()
event.wait() # 等待
event.set() # 设置
event.clear() # 清除
# 条件变量
cv = threading.Condition()
cv.wait()
cv.notify()
cv.notify_all()
# 队列
from queue import Queue
q = Queue()
q.put(1)
q.get()
#include <thread>
#include <mutex>
#include <condition_variable>
#include <queue>
#include <iostream>
void worker(int n) {
std::cout << "Thread " << n << " started" << std::endl;
}
int main() {
// 创建线程
std::thread t1(worker, 1);
std::thread t2(worker, 2);
t1.join();
t2.join();
// Lambda 线程
std::thread t3([](int x) {
std::cout << x * 2 << std::endl;
}, 5);
t3.join();
return 0;
}
#include <mutex>
std::mutex mtx;
void safe_increment() {
std::lock_guard<std::mutex> lock(mtx); // RAII 锁
// 临界区
counter++;
} // 锁自动释放
// 或手动
mtx.lock();
counter++;
mtx.unlock();
// unique_lock - 更灵活
std::unique_lock<std::mutex> lock(mtx, std::defer_lock);
// ... 做其他事 ...
lock.lock();
// ... 临界区 ...
#include <condition_variable>
#include <mutex>
#include <queue>
std::mutex mtx;
std::condition_variable cv;
std::queue<int> q;
void producer() {
for (int i = 0; i < 10; ++i) {
{
std::lock_guard<std::mutex> lock(mtx);
q.push(i);
}
cv.notify_one();
}
}
void consumer() {
while (true) {
std::unique_lock<std::mutex> lock(mtx);
cv.wait(lock, [] { return !q.empty() || done; });
if (q.empty()) break;
int val = q.front();
q.pop();
lock.unlock();
// 处理 val
}
}
#include <future>
#include <iostream>
int async_task(int x) {
return x * 2;
}
int main() {
// 异步执行
std::future<int> f = std::async(std::launch::async, async_task, 42);
int result = f.get(); // 阻塞直到完成
std::cout << result << std::endl;
return 0;
}
维度线程进程
内存共享共享内存独立内存
创建开销小大
通信简单(共享内存)复杂(IPC)
稳定性一个线程崩溃可能影响其他更隔离
Python GIL受限不受影响

Python GIL:

import threading
import time
# CPU 密集型 - GIL 限制
def cpu_task():
while True:
x = 1 + 2
t1 = threading.Thread(target=cpu_task)
t2 = threading.Thread(target=cpu_task)
t1.start()
t2.start()
# 两个线程不能真正并行执行!

C++ 无 GIL:

#include <thread>
#include <vector>
void cpu_task() {
volatile long x = 0;
for (long i = 0; i < 1e9; ++i) {
x += 1;
}
}
int main() {
std::vector<std::thread> threads;
for (int i = 0; i < 4; ++i) {
threads.emplace_back(cpu_task);
}
for (auto& t : threads) {
t.join();
}
// 真正并行执行!
return 0;
}
  • std::filesystem 处理文件和目录
  • std::getenv / std::setenv 处理环境变量
  • C++20 std::process 提供进程管理
  • std::thread 和 std::mutex 处理线程

下章预告:ch11 错误处理与异常。