信号量的一个小实验。各种参数烦人。。
通过信号来实现线程的同步~~~~~~
程序不难~
semun.h
#ifndef _SEMUN_H
#define _SEMUN_H
union semun {
int val; /* value for SETVAL */
struct semid_ds *buf; /* buffer for IPC_STAT, IPC_SET */
unsigned short int *array; /* array for GETALL, SETALL */
struct seminfo *__buf; /* buffer for IPC_INFO */
};
#endif
这是sem1.c
/*
============================================================================
Name : c.c
Author : zwy
Version :
Copyright : Your copyright notice
Description : Hello World in C, Ansi-style
============================================================================
*/
/*
* sem_id((key_t)1234,1,0666|IPC_CREAT) 获取一个信号量标识符
* semctl(sem_id,0,SETVAL,sem_union); sem_id 标识符 STVAL信号量的初始化 sem_union 0表示的是这是第一个也是唯一一个信号量。
* IPC_RMID 用来删除 一个信号量
*semop(int sem_id,struct sembuf *sem_ops,size_t num_ops);
*struct{
short sem_num;//除非你使用的实一组信号量,否则它的取值一般为零
short sem_op;//一般上实+1,或者-1 表示对p,v操作
short sem_flag;//一般上被设置维sem_undo表示使当前操作系统跟踪这个信号量,如果这个进程在没有释放信号量的情况下中止,这个信号量将被系统自动释放。
};
*
* 初始化 sem_union
* */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/sem.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include "semun.h"
static int set_semvalue(void);
static void del_semvalue(void);
static int semaphore_p(void);
static int semaphore_v(void);
static int sem_id;
int main(int argc ,char * argv[])
{
int i;
int pause_time;
char op_char='0';
srand((unsigned int)getpid()); //引入伪随机的形式的时间分配。
sem_id = semget((key_t)1234,1,0666 | IPC_CREAT);
//通过semget来获取一个新的信号量的标识符,而ipc_create的作用实如果信号量不存在,就创建他
if(argc >1){
if(!set_semvalue()){
//初始化信号量
fprintf(stderr,"Failure to initialize semaphore!");
exit(EXIT_FAILURE);
}
op_char = 'X';
sleep(2);
}
for(i = 0 ; i < 10 ; i++)
{
if(!semaphore_p()) exit(EXIT_FAILURE);
printf("%c",op_char); fflush(stdout);
pause_time = rand()%3;
sleep(pause_time);
printf("%c",op_char); fflush(stdout);
if(!semaphore_v()) exit(EXIT_FAILURE);
pause_time = rand() % 3;
sleep(pause_time);
}
printf("\n%d - finish\n",getpid());
if(argc >1){//等待其他程序将信号量释放,然后删除信号量,信号量很珍贵~
sleep(10);
del_semvalue();
}
return EXIT_SUCCESS;
}
static int set_semvalue(void)
{
union semun sem_union;
sem_union.val = 1;
if(semctl(sem_id , 0 , SETVAL ,sem_union) == -1) return 0;
return 1;
}
static void del_semvalue(void)
{
union semun sem_union;
if(semctl(sem_id, 0, IPC_RMID,sem_union) == -1)
{
fprintf(stderr,"Failure to delete semaphore");
}
}
static int semaphore_p(void)
{
struct sembuf sem_b;
sem_b.sem_num = 0 ;
sem_b.sem_op = -1;
sem_b.sem_flg = SEM_UNDO;
if(semop(sem_id,&sem_b,1)==-1){
fprintf(stderr,"semaphore_p failure\n");
return ;
}
return 1;
}
static int semaphore_v(void)
{
struct sembuf sem_b;
sem_b.sem_num = 0 ;
sem_b.sem_op = 1;
sem_b.sem_flg = SEM_UNDO;
if(semop(sem_id,&sem_b,1) == -1){
fprintf(stderr,"semaphore_v failure\n");
return 0;
}
return 1;
}