1.7 信号量简述,进程之间的flage

(我记得好像也是友善的代码~~~~好像是,好像也不是~~~~)

Linux信号量简介

1:信号量

信号量(Semaphore),有时被称为信号灯,是在多线程环境下使用的一种设施,是可以用来保证两个或多个关键代码段不被并发调用。在进入一个关键代码段之前,线程必须获取一个信号量;一旦该关键代码段完成了,那么该线程必须释放信号量。

信号量类似于线程一章中使用的互斥锁,但更强大,信号量可以在数个(大于两个)线程中使用,而且可以使用信号集管理大量的信号量。同样,信号量也有有名信号量和无名信号量。

信号量的使用主要是用来保护共享资源,使得资源在一个时刻只有一个进程(线程)所拥有。

信号量的值为正的时候,说明它空闲。所测试的线程可以锁定而使用它。若为0,说明它被占用,测试的线程要进入睡眠队列中,等待被唤醒。

2:简单的信号量程序

程序简述:

程序描述了最简单的无名信号量的用法,类似与互斥锁。至于有名信号量在初始化部分有所不同,而且在结束时需要释放。下面提供的三个程序,第一个为无名信号量在线程程间的应用,其余两个为有名信号量在两个进程间的应用。

重点掌握函数:

pthread_join()

sem_init()

sem_wait()

sem_post()

sem_open()

Shmat()

sem_close()

     sem_unlink()

shmctl()

程序代码:

#include <pthread.h>   
//信号集所在库
#include <sys/sem.h>
//信号量所在库
#include <semaphore.h>  
#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
//编译时需要添加库  gcc -pthread -o outfile.out filename.c
int number;   // 被保护的全局变量
sem_t sem_id1, sem_id2;  //信号量!!若在进程中只需要定义一个,因为系统 //会复制一份出来
void* thread_one_fun(void *arg)
{
sem_wait(&sem_id1);		//如果信号量不为0则减一
printf("thread_one have the semaphore\n");
number++;
printf("number = %d\n",number);			//输出加一后的值
sem_post(&sem_id2);		//信号量加一
}

void* thread_two_fun(void *arg)
{
sem_wait(&sem_id2);		//如果信号量不为0则减一
printf("thread_two have the semaphore \n");
number--;
printf("number = %d\n",number); //输出减一后的值
	sem_post(&sem_id1);			//信号量加一
}

int main(int argc,char *argv[])
{
    number = 1;
	pthread_t id1, id2;
  sem_init(&sem_id1, 0, 1);  // 信号空闲的
  sem_init(&sem_id2, 0, 0);  // 信号忙的

	pthread_create(&id1,NULL,thread_one_fun, NULL);//建立线程1
	pthread_create(&id2,NULL,thread_two_fun, NULL);//建立线程2
	pthread_join(id1,NULL);	//等待线程1结束
	pthread_join(id2,NULL);	//等待线程2结束
	printf("this is main\n");		
	return 0;					//程序结束返回正常标志
}


有名信号量在两个进程间使用,有名信号量使用了两个c文件生成两个进程,通过信号量管理共享内存归谁调用:

//Server.c内容: 
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <semaphore.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#define SHMSZ 27
char SEM_NAME[]= "vik";

int main()
{
    char ch;
    int shmid;
    key_t key;
    char *shm,*s;
    sem_t *mutex;			//信号量

    //name the shared memory segment
    key = 1000;									//有名信号的内存段

    //create & initialize semaphore
    mutex = sem_open(SEM_NAME,O_CREAT,0644,1);//创建和初始化信号量 
    if(mutex == SEM_FAILED)						//如果创建失败则
    {
      perror("unable to create semaphore");
      sem_unlink(SEM_NAME);						//删除信号量并退出
      exit(-1);
    }

    //create the shared memory segment with this key
    shmid = shmget(key,SHMSZ,IPC_CREAT|0666);//创建共享内存段的关键 
    if(shmid<0)									//如果失败则输出错误
{													//并且退出
        perror("failure in shmget");
        exit(-1);
}

    //attach this segment to virtual memory
    shm = shmat(shmid,NULL,0);			//将这段共享内存虚拟化

    //start writing into memory
    s = shm;							//记录这段虚拟内存
    for(ch='A';ch<='Z';ch++)
    {
        sem_wait(mutex);				//信号量自减等待客户端的信号量增加 
        *s++ = ch;					//在共享内存地址上写入字符
        sem_post(mutex);				//信号量自加释放信号量
     }

    //the below loop could be replaced by binary semaphore
    while(*shm != '*')		
    {
        sleep(1);
}
    sem_close(mutex);				//关闭信号量,信号量被清0
    sem_unlink(SEM_NAME);			//正常释放信号量,若不为0则等其为										//0
    shmctl(shmid, IPC_RMID, 0);		//关闭共享内存
    exit(0);							//退出
}
///

//Client.c内容
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <semaphore.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#define SHMSZ 27
char SEM_NAME[]= "vik";

int main()
{
    char ch;
    int shmid;
    key_t key;
    char *shm,*s;
    sem_t *mutex;

    //name the shared memory segment
    key = 1000;

    //create & initialize existing semaphore
    mutex = sem_open(SEM_NAME,0,0644,0);		//打开已存在的信号量
    if(mutex == SEM_FAILED)						
    {
        perror("reader:unable to execute semaphore");
        sem_close(mutex);
        exit(-1);
    }

    //create the shared memory segment with this key
    shmid = shmget(key,SHMSZ,0666);		//打开共享内存
    if(shmid<0)
    {
        perror("reader:failure in shmget");
        exit(-1);
    }

    //attach this segment to virtual memory
    shm = shmat(shmid,NULL,0);				//虚拟共享内存

    //start reading
    s = shm;
    for(s=shm;*s!=NULL;s++)
    {
      sem_wait(mutex);						//等待其他进程释放信号
        putchar(*s);							//输出共享内存中的字符
      sem_post(mutex);						//释放信号
    }

  //once done signal exiting of reader:This can be replaced by another semaphore
    *shm = '*';					//关闭信号量和共享内存
    sem_close(mutex);
    shmctl(shmid, IPC_RMID, 0);
    exit(0);
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值