线程同步-信号量

1.信号量的数据类型sem_t本质是一个长整型的数,相关头文件semaphore.h
2.信号量初始化
  原型:extern int sem_init (sem_t *__sem, int __pshared, unsigned int __value)
  参数:sem是一个信号量指针;
          pshared为0只能在当前进程的所有线程间共享,否则在进程间共享
          value指的信号量的初始值,这里一般为0
   说明:linux线程一般不支持进程间的信号量共享,pshared为非0会报错    
3.信号量控制函数
  原型:extern int sem_post (sem_t *__sem)和extern int sem_wait (sem_t *__sem)
  参数:sem初始化过的信号量指针   
  说明:前者作用是为信号量的值加1,后者对信号量的值减1,当信号量为0后者阻塞等待,前者执行
          如果有两个线程都在等待同一个信号量变成非0值,那么被第三个线程改变信号量时,只能
         有一个线程可以对信号量做减法,另一个继续等待
4.获取信号量的值
  原型:extern int sem_getvalue (sem_t *__restrict __sem, int *__restrict __sval)
  参数:sem初始化过的信号量指针 
          sval为一个int型的指针,保存信号量的值
5.销毁信号量
  原型:extern int sem_destroy (sem_t *__sem)

  参数:sem初始化过的信号量指针    

测试:

#include <pthread.h>
#include"/home/zxd/zxd/semaphore.h"
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
FILE *fp;
sem_t bin_sem;//定义全局变量

void *thread1(void *arg)
{
  int m;
  int value1;
  printf("thread1--sem_wait\n");
  sem_getvalue(&bin_sem,&value1);
  printf("value1=%d\n",value1);
  sem_wait(&bin_sem);
  printf("thread1 sem_wait done!\n");
  sem_getvalue(&bin_sem,&value1);
  printf("value1=%d\n",value1);
  while (1)
  {
   printf("thread1 is runing!\n");
   if((m=fgetc(fp))!=EOF)
   {
   	printf("thread1 get word is:%c\n",m);
   }
  else
   {
  	exit(0);//读完退出
   }
   sleep(1);
  }
}

void *thread2(void *arg)
{
  int m;
  printf("thread2--sem_wait\n");
  sem_wait(&bin_sem);
  printf("thread2 sem_wait done!\n");
  while (1)
  {
   printf("thread2 is runing!\n");
   if((m=fgetc(fp))!=EOF)
   {
   	printf("thread2 get word is:%c\n",m);
   }
   else
   {
  	exit(0);//读完退出
   }
  sleep(1);
  }
}

void *thread3(void *arg)
{
  int n;
  int value3;
  printf("thread3---sem_post\n");
  sem_getvalue(&bin_sem,&value3);
  printf("value3=%d\n",value3);
  sem_post(&bin_sem);
  printf("thread3 sem_post done!\n");
  sem_getvalue(&bin_sem,&value3);
  printf("value3=%d\n",value3);
  while (1)
  {
   printf("thread3 is runing!\n");
   if((n=fgetc(fp))!=EOF)
   {
   	printf("thread3 get word is:%c\n",n);
   }
   else 
   {
     exit(0);//读完退出
   }
   sleep(1);
  }
}
int main()
{
 int res;
 pthread_t a_thread;
 void *thread_result;
 int a;
 fp=fopen("/home/zxd/zxd/1.txt","r");
 res = sem_init(&bin_sem, 0,0);
 sem_getvalue(&bin_sem,&a);
 printf("a=%d\n",a);
 if (res != 0)
 {
  perror("sem_init error!\n");
 }
  printf("sem_init done!\n");
 res = pthread_create(&a_thread, NULL, thread1, NULL);
 if (res != 0)
 {
  perror("thread1 create error!\n");
 }
 sleep(5);
 res = pthread_create(&a_thread, NULL, thread2, NULL);
 if (res != 0)
 {
  perror("thread2 create error!\n");
 }
  
 res = pthread_create(&a_thread, NULL, thread3, NULL);
 if (res != 0)
 {
  perror("thread3 create error!\n");
 }
 
 sleep(1);
 while (1)
 {
    sleep(3);//等待线程工作防止程序退出
 }

 return 0;
}
测试结果:

编译:gcc xhl.c -lpthread

[root@libmaster zxd]# ./a.out 
a=0
sem_init done!
thread1--sem_wait
value1=0
thread2--sem_wait
thread3---sem_post
value3=0
thread3 sem_post done!
value3=1
thread3 is runing!
thread1 sem_wait done!
value1=0
thread1 is runing!
thread3 get word is:q
thread1 get word is:w
thread3 is runing!
thread3 get word is:e
thread1 is runing!
thread1 get word is:r
thread3 is runing!
thread3 get word is:t
thread1 is runing!
thread1 get word is:


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java信号是一种线同步的机制,它可以用来控制同时访问某个资源的线程数。Semaphore类是Java提供的信号实现类,它有两个常用的方法:acquire()和release()。acquire()方法会尝试获取一个许可,如果没有许可可用,则会阻塞线程直到有许可可用。release()方法会释放一个许可,如果有阻塞的线程正在等待许可,则会选择一个线程并将其唤醒。 以下是一个使用Semaphore实现线同步的例子: ```java import java.util.concurrent.Semaphore; public class MyThread implements Runnable { private Semaphore semaphore; private int id; public MyThread(Semaphore semaphore, int id) { this.semaphore = semaphore; this.id = id; } @Override public void run() { try { semaphore.acquire(); System.out.println("Thread " + id + " is running"); Thread.sleep(1000); System.out.println("Thread " + id + " is done"); semaphore.release(); } catch (InterruptedException e) { e.printStackTrace(); } } public static void main(String[] args) { Semaphore semaphore = new Semaphore(2); // 最多允许2个线程同时运行 for (int i = 0; i < 5; i++) { new Thread(new MyThread(semaphore, i)).start(); } } } ``` 上述代码中,Semaphore的初始值为2,表示最多允许2个线程同时运行。在run()方法中,线程首先会尝试获取一个许可,如果没有许可可用,则会阻塞线程直到有许可可用。然后线程会执行一些操作,最后释放许可。在main()方法中,创建了5个线程并启动它们。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值