sem_wait生产者
时间: 2023-09-22 11:03:19 浏览: 56
sem_wait是一个用于线程同步的函数,它主要用于控制多个线程之间对某个共享资源的访问。在生产者-消费者模型中,生产者线程一般负责生产产品并将其放入共享资源(例如缓冲区),而消费者线程则从共享资源中取出产品进行消费。
当生产者线程准备向共享资源添加一个产品时,它需要先调用sem_wait函数来等待信号量。信号量是一个用于控制其他线程对资源访问的计数器,当计数器值大于0时,说明资源可供访问;当计数器值为0时,说明资源正在被其他线程占用,需要等待。
在生产者-消费者模型中,通常会使用两个信号量。一个是用来记录共享资源中可以放置产品的空位数量,另一个是用来记录共享资源中已存在的产品数量。在生产者添加产品时,它会先调用sem_wait函数来等待空位信号量,当空位信号量的值大于0时,说明还有空位可以放置产品,生产者线程就可以放置产品,并将空位信号量的值减1,表示占用了一个空位。然后生产者线程再调用sem_post函数来增加产品信号量的值,表示共享资源中已经存在了一个产品。
总之,sem_wait函数在生产者中的作用是用来等待空位信号量的值大于0,表示还有空位可以放置产品。只有当空位信号量的值大于0时,生产者线程才能继续执行下去,并将空位信号量的值减1,表示占用了一个空位。
相关问题
sem_wait 编程示例
`sem_wait()` 是 POSIX 信号量的一个函数,用于等待一个信号量变为可用。如果该信号量当前不可用,则 `sem_wait()` 将阻塞调用它的线程,直到该信号量可用为止。
下面是一个 `sem_wait()` 的示例:
```c
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#define MAX_ITEMS 5
int buffer[MAX_ITEMS];
int fill = 0;
int use = 0;
sem_t empty_sem;
sem_t full_sem;
pthread_mutex_t buffer_mutex;
void put(int value) {
buffer[fill] = value;
fill = (fill + 1) % MAX_ITEMS;
}
int get() {
int tmp = buffer[use];
use = (use + 1) % MAX_ITEMS;
return tmp;
}
void *producer(void *arg) {
int i;
for (i = 0; i < MAX_ITEMS * 2; i++) {
sem_wait(&empty_sem);
pthread_mutex_lock(&buffer_mutex);
put(i);
pthread_mutex_unlock(&buffer_mutex);
sem_post(&full_sem);
}
return NULL;
}
void *consumer(void *arg) {
int i, tmp = 0;
while (tmp != MAX_ITEMS * 2 - 1) {
sem_wait(&full_sem);
pthread_mutex_lock(&buffer_mutex);
tmp = get();
printf("Got: %d\n", tmp);
pthread_mutex_unlock(&buffer_mutex);
sem_post(&empty_sem);
}
return NULL;
}
int main(int argc, char *argv[]) {
pthread_t prod, cons;
sem_init(&empty_sem, 0, MAX_ITEMS);
sem_init(&full_sem, 0, 0);
pthread_mutex_init(&buffer_mutex, NULL);
pthread_create(&prod, NULL, producer, NULL);
pthread_create(&cons, NULL, consumer, NULL);
pthread_join(prod, NULL);
pthread_join(cons, NULL);
sem_destroy(&empty_sem);
sem_destroy(&full_sem);
pthread_mutex_destroy(&buffer_mutex);
return 0;
}
```
这个示例演示了如何使用 `sem_wait()` 和 `sem_post()` 函数来实现线程之间的同步。在这个示例中,生产者线程往缓冲区中写入数据,消费者线程从缓冲区中读取数据,通过使用信号量和互斥锁来保证线程之间的同步。
sem_open sem_wait实现两个进程读写共享内存的同步的示例代码,包含非fork的进程1和进程2,两个信号量
下面是一个使用 `sem_open` 和 `sem_wait` 实现两个进程读写共享内存的同步的示例代码,包含非 fork 的进程 1 和进程 2,两个信号量。
进程 1:
```c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <semaphore.h>
#include <sys/mman.h>
#define SHARED_MEMORY_NAME "/shared_memory"
#define SEM_MUTEX_NAME "/sem_mutex"
#define SEM_EMPTY_NAME "/sem_empty"
#define SEM_FULL_NAME "/sem_full"
#define MAX_BUFFER_SIZE 10
typedef struct shared_memory {
int buffer[MAX_BUFFER_SIZE];
int head;
int tail;
} shared_memory_t;
int main() {
// 创建或打开共享内存
int fd = shm_open(SHARED_MEMORY_NAME, O_CREAT | O_RDWR, 0666);
if (fd < 0) {
perror("shm_open");
exit(1);
}
if (ftruncate(fd, sizeof(shared_memory_t)) < 0) {
perror("ftruncate");
exit(1);
}
shared_memory_t *shared_memory = (shared_memory_t *) mmap(NULL, sizeof(shared_memory_t), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (shared_memory == MAP_FAILED) {
perror("mmap");
exit(1);
}
// 创建或打开互斥锁信号量
sem_t *sem_mutex = sem_open(SEM_MUTEX_NAME, O_CREAT, 0666, 1);
if (sem_mutex == SEM_FAILED) {
perror("sem_open mutex");
exit(1);
}
// 创建或打开空信号量
sem_t *sem_empty = sem_open(SEM_EMPTY_NAME, O_CREAT, 0666, MAX_BUFFER_SIZE);
if (sem_empty == SEM_FAILED) {
perror("sem_open empty");
exit(1);
}
// 创建或打开满信号量
sem_t *sem_full = sem_open(SEM_FULL_NAME, O_CREAT, 0666, 0);
if (sem_full == SEM_FAILED) {
perror("sem_open full");
exit(1);
}
// 写入共享内存
for (int i = 0; i < MAX_BUFFER_SIZE; i++) {
sem_wait(sem_empty); // 等待空信号量
sem_wait(sem_mutex); // 等待互斥锁信号量
shared_memory->buffer[shared_memory->head] = i;
shared_memory->head = (shared_memory->head + 1) % MAX_BUFFER_SIZE;
sem_post(sem_mutex); // 发送互斥锁信号量
sem_post(sem_full); // 发送满信号量
printf("Producer put: %d\n", i);
sleep(1); // 模拟生产者速度慢
}
// 关闭和删除共享内存
if (munmap(shared_memory, sizeof(shared_memory_t)) < 0) {
perror("munmap");
exit(1);
}
if (shm_unlink(SHARED_MEMORY_NAME) < 0) {
perror("shm_unlink");
exit(1);
}
// 关闭和删除信号量
if (sem_close(sem_mutex) < 0) {
perror("sem_close mutex");
exit(1);
}
if (sem_close(sem_empty) < 0) {
perror("sem_close empty");
exit(1);
}
if (sem_close(sem_full) < 0) {
perror("sem_close full");
exit(1);
}
if (sem_unlink(SEM_MUTEX_NAME) < 0) {
perror("sem_unlink mutex");
exit(1);
}
if (sem_unlink(SEM_EMPTY_NAME) < 0) {
perror("sem_unlink empty");
exit(1);
}
if (sem_unlink(SEM_FULL_NAME) < 0) {
perror("sem_unlink full");
exit(1);
}
return 0;
}
```
进程 2:
```c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <semaphore.h>
#include <sys/mman.h>
#define SHARED_MEMORY_NAME "/shared_memory"
#define SEM_MUTEX_NAME "/sem_mutex"
#define SEM_EMPTY_NAME "/sem_empty"
#define SEM_FULL_NAME "/sem_full"
#define MAX_BUFFER_SIZE 10
typedef struct shared_memory {
int buffer[MAX_BUFFER_SIZE];
int head;
int tail;
} shared_memory_t;
int main() {
// 打开共享内存
int fd = shm_open(SHARED_MEMORY_NAME, O_RDWR, 0666);
if (fd < 0) {
perror("shm_open");
exit(1);
}
shared_memory_t *shared_memory = (shared_memory_t *) mmap(NULL, sizeof(shared_memory_t), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (shared_memory == MAP_FAILED) {
perror("mmap");
exit(1);
}
// 打开互斥锁信号量
sem_t *sem_mutex = sem_open(SEM_MUTEX_NAME, 0);
if (sem_mutex == SEM_FAILED) {
perror("sem_open mutex");
exit(1);
}
// 打开空信号量
sem_t *sem_empty = sem_open(SEM_EMPTY_NAME, 0);
if (sem_empty == SEM_FAILED) {
perror("sem_open empty");
exit(1);
}
// 打开满信号量
sem_t *sem_full = sem_open(SEM_FULL_NAME, 0);
if (sem_full == SEM_FAILED) {
perror("sem_open full");
exit(1);
}
// 读取共享内存
for (int i = 0; i < MAX_BUFFER_SIZE; i++) {
sem_wait(sem_full); // 等待满信号量
sem_wait(sem_mutex); // 等待互斥锁信号量
int value = shared_memory->buffer[shared_memory->tail];
shared_memory->tail = (shared_memory->tail + 1) % MAX_BUFFER_SIZE;
sem_post(sem_mutex); // 发送互斥锁信号量
sem_post(sem_empty); // 发送空信号量
printf("Consumer get: %d\n", value);
sleep(2); // 模拟消费者速度慢
}
// 关闭和删除共享内存
if (munmap(shared_memory, sizeof(shared_memory_t)) < 0) {
perror("munmap");
exit(1);
}
if (shm_unlink(SHARED_MEMORY_NAME) < 0) {
perror("shm_unlink");
exit(1);
}
// 关闭和删除信号量
if (sem_close(sem_mutex) < 0) {
perror("sem_close mutex");
exit(1);
}
if (sem_close(sem_empty) < 0) {
perror("sem_close empty");
exit(1);
}
if (sem_close(sem_full) < 0) {
perror("sem_close full");
exit(1);
}
return 0;
}
```
相关推荐
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![pdf](https://img-home.csdnimg.cn/images/20210720083512.png)
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)