Linux 中,C 多线程通信可通过共享全局变量、传递参数、条件变量、
Linux C编程中,多线程通信是实现并发程序功能的关键部分,以下是几种常见的多线程通信方法及其详细描述:
信号量(Semaphore)
信号量是一种用于线程同步的计数器,可以控制多个线程对共享资源的访问,它分为二进制信号量和计数信号量两种。
| 类型 | 说明 | 用途 |
|---|---|---|
| 二进制信号量 | 只有0和1两个状态,类似于互斥锁 | 主要用于互斥访问共享资源 |
| 计数信号量 | 可以取任意非负整数值 | 用于控制对多个相同资源的访问 |
使用方法:
- 初始化:
sem_init() - P操作(等待):
sem_wait() - V操作(释放):
sem_post() - 销毁:
sem_destroy()
示例代码:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
sem_t sem;
void *thread_func(void *arg) {
sem_wait(&sem); // P操作
printf("Thread %d is in critical section
", *(int *)arg);
sleep(1); // 模拟临界区操作
printf("Thread %d leaves critical section
", *(int *)arg);
sem_post(&sem); // V操作
return NULL;
}
int main() {
pthread_t threads[5];
int thread_ids[5];
sem_init(&sem, 0, 1); // 初始化二进制信号量为1
for (int i = 0; i < 5; i++) {
thread_ids[i] = i;
pthread_create(&threads[i], NULL, thread_func, &thread_ids[i]);
}
for (int i = 0; i < 5; i++) {
pthread_join(threads[i], NULL);
}
sem_destroy(&sem); // 销毁信号量
return 0;
}
互斥锁(Mutex)与条件变量(Condition Variable)
互斥锁用于保护共享资源,确保同一时刻只有一个线程可以访问该资源,条件变量则用于线程间的等待和通知机制。
使用方法:
- 初始化互斥锁:
pthread_mutex_init() - 加锁:
pthread_mutex_lock() - 解锁:
pthread_mutex_unlock() - 销毁互斥锁:
pthread_mutex_destroy() - 初始化条件变量:
pthread_cond_init() - 等待条件变量:
pthread_cond_wait() - 发出条件变量信号:
pthread_cond_signal()或pthread_cond_broadcast() - 销毁条件变量:
pthread_cond_destroy()
示例代码:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
pthread_mutex_t mutex;
pthread_cond_t cond;
int count = 0;
void *producer(void *arg) {
pthread_mutex_lock(&mutex);
count++;
printf("Producer: %d
", count);
pthread_cond_signal(&cond); // 通知消费者
pthread_mutex_unlock(&mutex);
return NULL;
}
void *consumer(void *arg) {
pthread_mutex_lock(&mutex);
while (count == 0) { // 如果计数为0,等待条件变量
pthread_cond_wait(&cond, &mutex);
}
printf("Consumer: %d
", count);
count--;
pthread_mutex_unlock(&mutex);
return NULL;
}
int main() {
pthread_t prod, cons;
pthread_mutex_init(&mutex, NULL);
pthread_cond_init(&cond, NULL);
pthread_create(&prod, NULL, producer, NULL);
pthread_create(&cons, NULL, consumer, NULL);
pthread_join(prod, NULL);
pthread_join(cons, NULL);
pthread_mutex_destroy(&mutex);
pthread_cond_destroy(&cond);
return 0;
}
消息队列(Message Queue)
消息队列允许线程之间通过发送和接收消息来进行通信,每个消息都包含一个优先级,系统会根据优先级将消息排序。
使用方法:
- 创建消息队列:
msgget() - 发送消息:
msgsnd() - 接收消息:
msgrcv() - 删除消息队列:
msgctl()
示例代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/msg.h>
struct msgbuf {
long mtype;
char mtext[100];
};
int main() {
key_t key = ftok("progfile", 65);
int msgid = msgget(key, 0666 | IPC_CREAT);
struct msgbuf message;
// 发送消息
message.mtype = 1;
strcpy(message.mtext, "Hello World");
msgsnd(msgid, &message, sizeof(message), 0);
printf("Message sent: %s
", message.mtext);
// 接收消息
msgrcv(msgid, &message, sizeof(message), 0, 0);
printf("Message received: %s
", message.mtext);
// 删除消息队列
msgctl(msgid, IPC_RMID, NULL);
return 0;
}
管道(Pipe)和命名管道(FIFO)
管道是一种单向通信机制,数据只能在一个方向上流动,命名管道(FIFO)则可以用于不相关的进程间通信。
使用方法:
- 创建管道:
pipe()(匿名管道)或mkfifo()(命名管道) - 读写管道:使用
read()和write()函数进行数据传输 - 关闭管道:
close()
示例代码(匿名管道):
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <pthread.h>
int pipefd[2];
void *writer(void *arg) {
char buffer[] = "Hello from writer";
write(pipefd[1], buffer, strlen(buffer)+1); // 写入管道
return NULL;
}
void *reader(void *arg) {
char buffer[100];
read(pipefd[0], buffer, sizeof(buffer)); // 从管道读取数据
printf("Reader received: %s
", buffer);
return NULL;
}
int main() {
pipe(pipefd); // 创建匿名管道
pthread_t wtid, rtid;
pthread_create(&wtid, NULL, writer, NULL);
pthread_create(&rtid, NULL, reader, NULL);
pthread_join(wtid, NULL);
pthread_join(rtid, NULL);
close(pipefd[0]); // 关闭读端
close(pipefd[1]); // 关闭写端
return 0;
}
共享内存(Shared Memory)
共享内存是最快的进程间通信方式之一,多个线程可以直接读写同一块内存区域,通常与信号量结合使用,以实现同步。
使用方法:
- 创建共享内存段:
shmget() - 附加到进程地址空间:
shmat() - 分离共享内存段:
shmdt() - 删除共享内存段:
shmctl()
示例代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <pthread.h>
int main() {
key_t key = ftok("shmfile",69); // 生成IPC键值
int shmid = shmget(key,1024,0666|IPC_CREAT); // 创建共享内存段
char *str = (char*) shmat(shmid,(void*)0,0); // 附加到进程地址空间
printf("Write Data: ");
fgets(str,1024,stdin); // 从标准输入读取数据到共享内存中
printf("Data written in memory: %s
",str); // 显示写入的数据内容
shmdt(str); // 分离共享内存段以防止未预期修改导致错误结果发生风险增加安全性考虑因素之一就是及时正确地释放资源避免资源泄露等问题产生负面影响甚至崩溃程序运行环境稳定性可靠性降低用户体验满意度下降等不良后果发生概率增大因此必须重视资源管理问题并采取相应措施加以解决才能保证软件产品质量达到较高水平满足用户需求期望值提升市场竞争力促进企业发展壮大进步!(此处仅为示例实际开发中应更加谨慎处理资源释放问题)
return 0;
}
小伙伴们,上文介绍linux c多线程如何通信的内容,你了解清楚吗?希望对你有所帮助,任何问题可以给我留言,让我们下期再见吧。
原创文章,发布者:酷番叔,转转请注明出处:https://cloud.kd.cn/ask/12093.html