c++ linux semaphore信号量的使用
sem_init函数是Posix信号量操作中的函数。sem_init() 初始化一个定位在 sem 的匿名信号量。value 参数指定信号量的初始值。 pshared 参数指明信号量是由进程内线程共享,还是由进程之间共享。如果 pshared 的值为 0,那么信号量将被进程内的线程共享,并且应该放置在这个进程的所有线程都可见的地址上(如全局变量,或者堆上动态分配的变量)。
如果 pshared 是非零值,那么信号量将在进程之间共享,并且应该定位共享内存区域(见 shm_open(3)、mmap(2) 和 shmget(2))。因为通过 fork(2) 创建的孩子继承其父亲的内存映射,因此它也可以见到这个信号量。所有可以访问共享内存区域的进程都可以用 sem_post(3)、sem_wait(3) 等等操作信号量。初始化一个已经初始的信号量其结果未定义。
返回值 :
sem_init() 成功时返回 0;错误时,返回 -1,并把 errno 设置为合适的值。
例子:
看我下面的代码, 父进程是消费者,子进程是生产者。REPEATS 决定总共生产的次数 (可以自己修改)
CONSUMER_SPEED 决定消费的速度 (越大越慢,可以自己修改)
PRODUCER_SPEED 决定生产的速度 (越大越慢,可以自己修改)
我的例子里,生产者生产一个随机数。另外消费速度比生产速度慢,所以可以看到输出中,+++ (生产者) 开头的出现的比--- (消费者)多,当生产者结束后,就只有 --- 打印了。
对这个程序由什么问题,可以baidu hi我。在linux/unix下用 gcc 编译。
#include <stdio.h>
#include <unistd.h>
#include <time.h>
#include <string.h>
#include <stdlib.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include <sys/stat.h>
#define REPEATS (10) /* count of production/consumption */
#define MAX_BUFFER_SIZE (8)
typedef struct
{
int bottom
int top
int data[MAX_BUFFER_SIZE]
} STRUCT_BUFFER
STRUCT_BUFFER * pBuffer = NULL
/* Define speed of consumer/producer, change them as u like */
#define PRODUCER_SPEED (1) /* 1/sec */
#define CONSUMER_SPEED (2) /* 1/2sec */
int sem_consume/* consumer sem */
int sem_produce/* producer sem */
int shm_buffer /* shared buffer */
#define FLAG (IPC_CREAT | S_IRWXU)
/* Init semphores &shared buffer */
void init()
{
union semun {
int val
struct semid_ds *buf
unsigned short *array
} arg
shm_buffer = shmget(0x1111, sizeof(STRUCT_BUFFER), FLAG)
pBuffer = shmat(shm_buffer, 0, 0)
memset(pBuffer, 0, sizeof(STRUCT_BUFFER))
sem_consume = semget(0x2222, 1, FLAG)
arg.val = 0
if (semctl(sem_consume, 0, SETVAL, arg) <0)
{
perror("Consumer")
exit(1)
}
sem_produce = semget(0x3333, 1, FLAG)
arg.val = MAX_BUFFER_SIZE
if (semctl(sem_produce, 0, SETVAL, arg) <0)
{
perror("Producer")
exit(1)
}
}
/* destroy semphores &shared buffer */
void deinit()
{
shmctl(shm_buffer, IPC_RMID, NULL)
semctl(sem_consume, 0, IPC_RMID)
semctl(sem_produce, 0, IPC_RMID)
}
int main()
{
int pid, i
struct sembuf sbuf
init()
printf("Start fork...\n")
pid = fork()
if (pid >0)
{
/* parent process, consumer */
for (i = 0i <REPEATSi++)
{
/* Try decrementing 1 from consumer */
sbuf.sem_num=0
sbuf.sem_op=-1
sbuf.sem_flg=0
semop(sem_consume, &sbuf, 1)
/* OK */
printf("Consumer get %6d\n", pBuffer->data[pBuffer->bottom])
pBuffer->bottom = (pBuffer->bottom+1)%MAX_BUFFER_SIZE
/* Try incrementing 1 to producer */
sbuf.sem_op = 1
semop(sem_produce, &sbuf, 1)
sleep(CONSUMER_SPEED)
}
wait(0)
shmdt(pBuffer)
}
else if (pid == 0)
{
srand(time(NULL))
/* child process, producer */
for (i = 0i <REPEATSi++)
{
/* Try decrementing 1 from producer */
sbuf.sem_num=0
sbuf.sem_op=-1
sbuf.sem_flg=0
semop(sem_produce, &sbuf, 1)
/* OK */
pBuffer->data[pBuffer->top] = (rand()%1000)*1000 + i + 1
printf("Producer put %6d\n", pBuffer->data[pBuffer->top])
pBuffer->top = (pBuffer->top+1)%MAX_BUFFER_SIZE
/* Try incrementing 1 to consumer */
sbuf.sem_op = 1
semop(sem_consume, &sbuf, 1)
sleep(PRODUCER_SPEED)
}
shmdt(pBuffer)
exit(0)
}
deinit()
return 0
}
#include<stdio.h>#include<pthread.h>
#include<unistd.h>
#include<fcntl.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<semaphore.h>
#include<stdlib.h>
#define N 3
pthread_mutex_t mutex_w,mutex_r// 定义读写互斥锁
sem_t sem_w,sem_r//定义读写信号量
int data[N]
int pos=0
void *function_w(void *arg)
{
int w = *(int *)arg
pos = w
while(1)
{
usleep(100000)
sem_wait(&sem_w)//等待可写的资源
pthread_mutex_lock(&mutex_w)//禁止别的线程写此资源
data[pos] = w
w++
w++
w++
pos++
pos=pos%N
pthread_mutex_unlock(&mutex_w)//别的线程可写此资源
sem_post(&sem_r)// 释放一个读资源
}
return (void *)0
}
void *function_r(void *arg)
{
while(1)
{
sem_wait(&sem_r)//等待可读的资源
pthread_mutex_lock(&mutex_r)//禁止别的线程读此资源
printf("%d\n",data[(pos+N-1)%N])
pthread_mutex_unlock(&mutex_r)//别的线程可读此资源
sem_post(&sem_w)// 释放一个写资源
}
return (void *)0
}
int main(int argc, char **argv)
{
pthread_t thread[2*N]
int i
pthread_mutex_init(&mutex_w,NULL)
pthread_mutex_init(&mutex_r,NULL)
sem_init(&sem_w,0,N)
sem_init(&sem_r,0,0)
for(i=0i<Ni++)
{
if ( pthread_create(&thread[i],NULL,function_w,(void *)&i) <0)//创建写线程
{
perror("pthread_create")
exit(-1)
}
}
for(i=Ni<2*Ni++)
{
if ( pthread_create(&thread[i],NULL,function_r,NULL) <0)//创建读线程
{
perror("pthread_create")
exit(-1)
}
}
sleep(1)
return(0)
}
欢迎分享,转载请注明来源:夏雨云
评论列表(0条)