今天有空就研究了下linux线程间的同步通信By信号量,离校钱只是匆匆的从网上看了一点概念性的东西(其实连概念也谈不上,就知道有信号量这么回事),对于具体的怎么用代码实现也不知道,现在正好有时间,研究了一下。
1、概念
1、信号量从本质上是一个非负整数计数器,是共享资源的数目,通常被用来控制对共享资源的访问。
2、信号量可以实现线程的同步和互斥
3、通过sem_post()和sem_wait()函数对信号量进行加减操作从而解决线程的同步和互斥。
4、信号量数据类型
sem_t
2、信号量创建和销毁
#include <semaphore.h>
int sem_init(sem_t *sem, int pshared, unsigned value);
int sem_destroy(sem_t *sem);
返回: 成功返回0,出错返回错误编号
参数:
sem:
信号量指针
pshared:
是否在进程间共享的标志,0为不共享,1为共享。
value
信号量的初始值
3、信号量的加和减操作
#include <semaphore.h>
int sem_post(sem_t *sem);
功能: 增加信号量的值
int sem_wait(sem_t *sem);
功能: 减少信号量的值
int sem_trywait(sem_t *sem);
功能: sem_wait()的非阻塞版本
返回: 成功返回0,出错返回错误编号
调用sem_post(): 一次信号量作加1操作
调用sem_wait():一次信号量作减1操作
当线程调用sem_wait()后,若信号量的值小于0则线程
阻塞。只有其它线程在调用sem_post()对信号量作加
操作后并且其值大于或等于0时,阻塞的线程才能继续运行。
5、例[利用线程信号量使三个线程交替循环输出10次]
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <semaphore.h>
#if 0
int sem_init(sem_t *sem, int pshared, unsigned int value);
int sem_destroy(sem_t *sem);
int sem_wait(sem_t *sem);
int sem_trywait(sem_t *sem);
int sem_timedwait(sem_t *sem, const struct timespec *abs_timeout);
int sem_post(sem_t *sem);
#endif
sem_t sem[3];
char ch = 'a';
void *th1(void *arg)
{
int i = 0;
while(i < 4)
{
sleep(2);
i++;
sem_wait(&sem[0]);
printf("@(%d),%c\n",(int)pthread_self(),ch);
ch = ch + 1;
sem_post(&sem[1]);
}
return (void*)0;
}
void *th2(void *arg)
{
int i = 0;
while(i < 4)
{
sleep(2);
i++;
sem_wait(&sem[1]);
printf("%c\n",ch);
sem_post(&sem[2]);
}
return (void*)0;
}
void *th3(void *arg)
{
sleep(2);
int i = 0;
while(i < 4)
{
i++;
sem_wait(&sem[2]);
printf("tangsong success!\n");
sem_post(&sem[0]);
}
return (void*)0;
}
int main(void)
{
pthread_t thread[3];
int i = 0;
sem_init(&sem[0],0,1);
sem_init(&sem[1],0,0);
sem_init(&sem[2],0,0);
pthread_create(thread,NULL,th1,0);
pthread_create(thread+1,NULL,th2,0);
pthread_create(thread+2,NULL,th3,0);
for(i = 0;i < 3;i++)
{
pthread_join(thread[i],0);
}
for(i = 0;i < 3;i++)
{
sem_destroy(&sem[i]);
}
return 0;
}
tsong@tslinux:~/summery/thread$ ./sem
@(1501783808),a
b
tangsong success!
@(1501783808),b
c
tangsong success!
@(1501783808),c
d
tangsong success!
@(1501783808),d
e
tangsong success!
执行结果如上