在多线程和多进程编程中,线程与进程之间的通讯是确保程序正确运行的关键。有效的通讯机制能够提高程序的效率和稳定性。本文将深入探讨线程与进程通讯的技巧,帮助开发者轻松实现多任务协作与数据同步。
线程间通讯
1. 共享内存
共享内存是线程间通讯最直接的方式。多个线程可以访问同一块内存区域,从而实现数据的共享。以下是使用C++11标准中的std::shared_mutex和std::unique_lock进行线程间共享内存通讯的示例代码:
#include <iostream>
#include <thread>
#include <mutex>
std::mutex mtx;
int shared_data = 0;
void thread_function() {
std::unique_lock<std::mutex> lock(mtx);
shared_data += 1;
std::cout << "Thread " << std::this_thread::get_id() << " updated shared_data to " << shared_data << std::endl;
}
int main() {
std::thread t1(thread_function);
std::thread t2(thread_function);
t1.join();
t2.join();
return 0;
}
2. 等待/通知机制
等待/通知机制(也称为条件变量)允许一个或多个线程等待某个条件成立,而其他线程可以通知等待的线程条件已经成立。以下是使用C++11标准中的std::condition_variable和std::unique_lock进行线程间等待/通知通讯的示例代码:
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
std::mutex mtx;
std::condition_variable cv;
bool ready = false;
void wait_thread() {
std::unique_lock<std::mutex> lock(mtx);
cv.wait(lock, []{ return ready; });
std::cout << "Thread " << std::this_thread::get_id() << " received notification" << std::endl;
}
void notify_thread() {
std::unique_lock<std::mutex> lock(mtx);
ready = true;
cv.notify_one();
}
int main() {
std::thread t1(wait_thread);
std::thread t2(notify_thread);
t1.join();
t2.join();
return 0;
}
进程间通讯
1. 命名管道
命名管道是一种用于进程间通讯的机制,允许两个或多个进程通过管道进行数据交换。以下是使用Python进行命名管道进程间通讯的示例代码:
import os
import time
import msvcrt
# 创建命名管道
pipe = os.pipe()
# 创建两个进程
pid1 = os.fork()
if pid1 == 0:
# 子进程1
os.close(pipe[0]) # 关闭读端
os.write(pipe[1], 'Hello, World!\n'.encode()) # 写入数据
os.close(pipe[1]) # 关闭写端
os._exit(0)
else:
pid2 = os.fork()
if pid2 == 0:
# 子进程2
os.close(pipe[1]) # 关闭写端
data = os.read(pipe[0], 1024).decode() # 读取数据
os.close(pipe[0]) # 关闭读端
print(data)
os._exit(0)
else:
# 父进程
os.waitpid(pid1, 0)
os.waitpid(pid2, 0)
2. 消息队列
消息队列是一种用于进程间通讯的机制,允许进程将消息发送到队列中,其他进程可以从队列中读取消息。以下是使用C++进行消息队列进程间通讯的示例代码:
#include <iostream>
#include <sys/ipc.h>
#include <sys/msg.h>
struct message {
long msg_type;
char msg_text[100];
};
int main() {
key_t key = ftok("message_queue", 'a');
int msgid = msgget(key, 0666 | IPC_CREAT);
message msg;
msg.msg_type = 1;
strcpy(msg.msg_text, "Hello, World!");
msgsnd(msgid, &msg, sizeof(msg.msg_text), 0);
message received_msg;
msgrcv(msgid, &received_msg, sizeof(received_msg.msg_text), 1, 0);
std::cout << "Received message: " << received_msg.msg_text << std::endl;
return 0;
}
通过以上技巧,开发者可以轻松实现多任务协作与数据同步。在实际应用中,应根据具体需求选择合适的通讯机制,以提高程序的效率和稳定性。
