您的位置:首页 > 运维架构 > Linux

Linux下进程之间信号量互斥、同步

2014-12-08 11:20 363 查看
一、信号量

信号量一般的作用就是用在进程之间的互斥和同步操作,跟线程的锁机制差不多的作用。线程当然也可以使用信号量来进行互斥、同步。

二、程序示例

/*commom.h*/
#ifndef _COMMOM_H_
#define _COMMOM_H_

#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/types.h>
#include <unistd.h>

union semun
{
int val;
struct semid_ds *buf;
unsigned short *array;
};

int init_sem(int semid)
{
union semun sem;
sem.val = 1;
if (semctl(semid, 0, SETVAL, sem)==-1)
{
printf("set_sem failed!\n");
exit(1);
}
return 0;
}

int del_sem(int semid)
{
union semun sem;
if (semctl(semid, 0, IPC_RMID, sem)==-1)
{
printf("del_sem failed!\n");
exit(1);
}
return 0;
}

int create_sem(key_t key, int num_sems)
{
int semid;
semid = semget(key, num_sems, 0666|IPC_CREAT);
if (semid == -1)
{
printf("create_sem failed!\n");
exit(1);
}
return semid;
}

int sem_p(int semid)
{
struct sembuf sem_buf;
sem_buf.sem_num = 0;
sem_buf.sem_op = -1;
sem_buf.sem_flg = SEM_UNDO;
if (semop(semid, &sem_buf, 1)==-1)
{
printf("sem_p failed!\n");
exit(1);
}
return 0;
}

int sem_v(int semid)
{
struct sembuf sem_buf;
sem_buf.sem_num = 0;
sem_buf.sem_op = +1;
sem_buf.sem_flg = SEM_UNDO;
if (semop(semid, &sem_buf, 1)==-1)
{
printf("sem_p failed!\n");
exit(1);
}
return 0;
}
#endif

/*sem_write1.c*/
#include <stdio.h>
#include <stdlib.h>
#include "commom.h"

int main(void)
{
FILE *fp;
key_t key;
int semid;

key = ftok("./commom.h", 0);
printf("0x%x\n", key);
semid = create_sem(key, 1);
fp = fopen("./text.txt", "a+");
sem_p(semid);
fwrite("english\n", 8, 1, fp);
sem_v(semid);
sleep(5);
sem_p(semid);
fwrite("test\n", 5, 1, fp);
sem_v(semid);
sleep(5);
fclose(fp);
del_sem(semid);

return 0;
}

/*sem_write2.c*/
#include <stdio.h>
#include <stdlib.h>
#include "commom.h"

int main(void)
{
int semid;
key_t key;
FILE *fp;

fp = fopen("./text.txt", "a+");
key = ftok("./commom.h", 0);
printf("0x%x\n", key);
semid = create_sem(key, 1);
init_sem(semid);
sem_p(semid);
fwrite("hello\n", 6, 1, fp);
sem_v(semid);
sleep(5);
sem_p(semid);
fwrite("world\n", 6, 1, fp);
sem_v(semid);
fclose(fp);

return 0;
}

#makefile
CFLAGS = -Wall -g
CC = gcc
TARGET = sem_write1 sem_write2

all:$(TARGET)
sem_write1:sem_write1.o
$(CC) $(CFLAGS) -o $@ $^
sem_write2:sem_write2.o
$(CC) $(CFLAGS) -o $@ $^
%.o:%.c %.h
$(CC) -c -o $@ $<
clean:
rm -f $(TARGET) *.o


注意:先运行sem_write2,因为sem_write2有对信号量进行初始化的操作,然后才能进行P/V操作。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息