在上一篇文章中,讲述了线程中互斥锁的使用,达到对共享资源互斥使用。除了使用互斥锁,信号量,也就是操作系统中所提到的PV原语,能达到互斥和同步的效果,这就是今天我们所要讲述的信号量线程控制。
PV原语是对整数计数器信号量sem的操作,一次P操作可使sem减一,而一次V操作可是sem加一。进程(或线程)根据信号量的值来判断是否对公共资源具有访问权限。当信号量的值大于零或等于零的时候,该进程(或线程)具有对公共资源访问的权限,否则,当信号量的值小于时,该进程(或线程)就会被阻塞,直到信号量的值大于或等于一。
1、在LINUX中,实现了POSIX的无名信号量,主要用于线程间的互斥同步,下面将简单介绍一些函数接口:
(1)、sem_init
功能: 用于创建一个信号量,并初始化信号量的值。
头文件:
函数原型: int sem_init (sem_t* sem, int pshared, unsigned int value);
函数传入值: sem:信号量。
pshared:决定信号量能否在几个进程间共享。由于目前LINUX还没有实现进
程间共享信息量,所以这个值只能取0。
函数返回值: 0:成功。
-1:失败。
(2)其他函数。
int sem_wait (sem_t* sem);
int sem_trywait (sem_t* sem);
int sem_post (sem_t* sem);
int sem_getvalue (sem_t* sem);
int sem_destroy (sem_t* sem);
功能:sem_wait和sem_trywait相当于P操作,它们都能将信号量的值减一,两者的区别在
于若信号量的值小于零时,sem_wait将会阻塞进程,而sem_trywait则会立即返回。
sem_post相当于V操作,它将信号量的值加一,同时发出唤醒的信号给等待的进程
(或线程)。
sem_getvalue 得到信号量的值。
sem_destroy 摧毁信号量。
函数传入值: sem:信号量。
函数返回值: 同上。
2、函数实现。
-
#include
-
#include
-
#include
-
#include
-
#include
-
#include
-
-
#define return_if_fail(p) /
-
if((p) == 0){printf ("[%s]: func error!", __func__);return;}
-
-
typedef struct _PrivInfo
-
{
-
sem_t sem;
-
int lock_var;
-
time_t end_time;
-
}PrivInfo;
-
-
static void info_init (PrivInfo* thiz);
-
static void* pthread_func_1 (PrivInfo* thiz);
-
static void* pthread_func_2 (PrivInfo* thiz);
-
-
int main (int argc, char** argv)
-
{
-
pthread_t pt_1 = 0;
-
pthread_t pt_2 = 0;
-
int ret = 0;
-
PrivInfo* thiz = NULL;
-
-
thiz = (PrivInfo* )malloc (sizeof (PrivInfo));
-
if (thiz == NULL)
-
{
-
printf ("[%s]:Failed to malloc PrivInfo./n");
-
return -1;
-
}
-
-
info_init (thiz);
-
-
ret = pthread_create (&pt_1, NULL, (void*)pthread_func_1, thiz);
-
if (ret != 0)
-
{
-
perror ("pthread_1_create:");
-
}
-
-
ret = pthread_create (&pt_2, NULL, (void*)pthread_func_2, thiz);
-
if (ret != 0)
-
{
-
perror ("pthread_2_create:");
-
}
-
-
pthread_join (pt_1, NULL);
-
pthread_join (pt_2, NULL);
-
-
sem_destroy (&thiz->sem);
-
free (thiz);
-
thiz = NULL;
-
-
return;
-
}
-
-
static void info_init (PrivInfo* thiz)
-
{
-
return_if_fail (thiz != NULL);
-
-
thiz->lock_var = 0;
-
thiz->end_time = time(NULL) + 10;
-
-
sem_init (&thiz->sem, 0, 1);
-
-
return;
-
}
-
-
static void* pthread_func_1 (PrivInfo* thiz)
-
{
-
return_if_fail(thiz != NULL);
-
-
int i = 0;
-
-
while (time(NULL) < thiz->end_time)
-
{
-
sem_wait (&thiz->sem);
-
printf ("pthread: pthread1 get lock./n");
-
-
for (i = 0; i < 2; i ++)
-
{
-
thiz->lock_var ++;
-
sleep (1);
-
}
-
-
sem_post (&thiz->sem);
-
printf ("pthread1: pthread1 unlock/n");
-
-
sleep (1);
-
}
-
-
return;
-
}
-
-
static void* pthread_func_2 (PrivInfo* thiz)
-
{
-
return_if_fail (thiz != NULL);
-
-
while (time (NULL) < thiz->end_time)
-
{
-
sem_wait (&thiz->sem);
-
printf ("pthread2: pthread2 get lock!/n");
-
printf ("the lock_var = %d/n", thiz->lock_var);
-
-
sem_post (&thiz->sem);
-
printf ("phtread2: pthread2 unlock./n");
-
-
sleep (3);
-
}
-
-
return;
-
}
从上面的实例中可以看出,通过信号量实现共享资源中的互斥使用,跟上一篇文章中的互斥锁的效果是一样的。但是通过互斥锁还有一个更加方便的功能,就是同步。下一篇文章将讲述线程间通过信号量的同步实现。
~~END~~