操作函数
sem_t g_sem; /* 信号量定义 */
sem_init(&g_sem, 0, int value) /* 信号量初始化,value值为信号量的初始值 */
sem_destroy(&g_sem); /* 销毁信号量 */
sem_post(&g_sem); /* 发送信号 */
sem_wait(&g_sem); /* 等待信号到来 */
sem_timedwait(&g_sem, &ts); /* 超时等待信号,如果超时返回 ETIMEDOUT */
sem_wait 示例
示例1
thread_1等待thread_2发送信号,当其接收到信号的时候,才开始工作,如果没有信号,会一直等待下去
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <semaphore.h>
static sem_t g_sem;
static void *thread_1(void *data)
{
while(1) {
printf("thread_1 sem_wait ==1==\n");
sem_wait(&g_sem); /* 等待信号到来 */
printf("thread_1 sem_wait ==2==\n");
}
}
static void *thread_2(void *data)
{
while(1) {
sleep(1);
printf("thread_2 sem_post\n");
sem_post(&g_sem); /* 发送信号 */
}
}
int main(int argc, char const *argv[])
{
/* 信号量初始化,信号量初始值设为0 */
if (sem_init(&g_sem, 0, 0) != 0) {
printf("sem_init error\n");
return 0;
}
pthread_t pid[2];
pthread_create(&pid[0], NULL, thread_1, NULL);
pthread_create(&pid[1], NULL, thread_2, NULL);
pthread_join(pid[0], NULL);
pthread_join(pid[1], NULL);
sem_destroy(&g_sem);
return 0;
}
示例2
等待线程执行完成后才继续往后执行
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <semaphore.h>
static sem_t g_sem;
static void *thread_process(void *data)
{
int i = 0;
for (i = 0; i < 10; i++)
{
printf("TODO: %d\n", i);
sleep(1);
}
sem_post(&g_sem);
}
static void do_process()
{
sem_init(&g_sem, 0, 0);
pthread_t pid;
pthread_create(&pid, NULL, thread_process, NULL);
sem_wait(&g_sem);
sem_destroy(&g_sem);
}
int main(int argc, char const *argv[])
{
do_process();
printf("[main] do_process completion\n");
return 0;
}
sem_timedwait 示例
例子中thread_2将sem_post()注释掉,不发送信号,当超过10秒后,sem_timedwait()会返回超时,如果sem_post()正常发送信号,sem_timedwait()和sem_wait()功能上没有差异
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <errno.h>
#include <semaphore.h>
#define NSECTOSEC 1000000000
static sem_t g_sem;
static void *thread_1(void *data)
{
while(1) {
printf("thread_1 sem_wait ==1==\n");
struct timespec ts;
clock_gettime(CLOCK_REALTIME, &ts);
ts.tv_sec += 10; /* 等10s,超过10秒返回time out */
ts.tv_nsec += 0;
ts.tv_sec += ts.tv_nsec / NSECTOSEC;
ts.tv_nsec = ts.tv_nsec % NSECTOSEC;
int result = sem_timedwait(&g_sem, &ts); /* 超时等待信号,如果超时返回 ETIMEDOUT */
printf("sem_timewait result:%d errno:%d timeout_opcode:%d\n", result, errno, ETIMEDOUT);
printf("thread_1 sem_wait ==2==\n");
}
}
static void *thread_2(void *data)
{
while(1) {
sleep(1);
printf("thread_2 sem_post\n");
// sem_post(&g_sem); /* 不发送信号,让sem_timedwait超时 */
}
printf("thread_2 end!\n");
}
int main(int argc, char const *argv[])
{
/* 信号量初始化,信号量初始值设为0 */
if (sem_init(&g_sem, 0, 0) != 0) {
printf("sem_init error\n");
return 0;
}
pthread_t pid[2];
pthread_create(&pid[0], NULL, thread_1, NULL);
pthread_create(&pid[1], NULL, thread_2, NULL);
pthread_join(pid[0], NULL);
pthread_join(pid[1], NULL);
sem_destroy(&g_sem);
return 0;
}