c++ semaphore信号量的使用

c++ semaphore信号量的使用,第1张

目前网上可以查找到很多关于信号量的实现文章,但是讲解在linux下使用semaphore的文章比较少;

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)

}


欢迎分享,转载请注明来源:夏雨云

原文地址:https://www.xiayuyun.com/zonghe/147765.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-03-20
下一篇2023-03-20

发表评论

登录后才能评论

评论列表(0条)

    保存