POSIX信号量semaphore实现线程同步

POSIX标准定义了信号量接口如下,常常用于线程间同步。

#include <semaphore.h>

int sem_init(sem_t *sem, int pshared, unsigned int value);
int sem_destroy(sem_t *sem);
int sem_post(sem_t *sem);
int sem_wait(sem_t *sem);
  • sem_init()在sem指向的地址初始化未命名的信号量

        参数value指定信号量的初始值;
        参数pshared为0表示该信号量在线程之间共享,非零表示在进程之间(例如父进程和子进程)共享,并且位于共享内存区域;
        返回0表示成功,返回-1表示出错,可以读取errno值获取错误信息;

  • sem_destroy在sem所指向的地址处销毁未命名的信号量
  • sem_post()增加(unlock解锁)sem所指向的信号量。
  •  sem_wait()减少(lock锁定)sem指向的信号量。

        如果信号量的值大于零,则继续递减,函数立即返回。如果信号量当前的值为零,则调用阻塞,直到可以执行减量(即,信号量值上升到零以上),或者信号处理程序中断调用。

 程序示例

#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>
#include <time.h>

static sem_t g_sem_test;

static void *listen_thread(void *data)
{
	time_t time_now;

	while(1)
	{
		sem_wait(&g_sem_test);
		time(&time_now);
		printf("<%s, %d> %ld\n", __func__, __LINE__, time_now);
	}
}

int main(int argc, char *argv[])
{
	pthread_t td;
	pthread_attr_t attr;

	pthread_attr_init(&attr);
	pthread_attr_setstacksize(&attr, 256 * 1024);
	pthread_create(&td, &attr, listen_thread, NULL);
	pthread_attr_destroy(&attr);

	sem_init(&g_sem_test, 0, 0);
	while(1)
	{
		sem_post(&g_sem_test);
		sleep(10);
	}
	return 0;
}

编译运行如下图,main所在线程间隔10秒调用sem_post()增加信号量值,线程listen_thread在一个while循环中调用sem_wait()阻塞等待信号量,从该线程打印的UNIX时间戳来看间隔10秒“等到”了信号量,符合程序预期。

  • 9
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下面是一个使用 POSIX 信号量实现多个线程同时访问共享资源的例子: ```c #include <stdio.h> #include <stdlib.h> #include <pthread.h> #include <semaphore.h> #define MAX_THREADS 10 #define NUM_ITERATIONS 5 sem_t sem; // 定义信号量 int shared_resource = 0; // 共享资源 void *thread_func(void *arg) { int i; int id = *((int *) arg); for (i = 0; i < NUM_ITERATIONS; i++) { sem_wait(&sem); // 等待信号量 shared_resource++; // 访问共享资源 printf("Thread %d updated shared_resource to %d\n", id, shared_resource); sem_post(&sem); // 释放信号量 } pthread_exit(NULL); } int main(int argc, char *argv[]) { int i; pthread_t threads[MAX_THREADS]; int thread_ids[MAX_THREADS]; sem_init(&sem, 0, 1); // 初始化信号量 for (i = 0; i < MAX_THREADS; i++) { thread_ids[i] = i; pthread_create(&threads[i], NULL, thread_func, (void *) &thread_ids[i]); } for (i = 0; i < MAX_THREADS; i++) { pthread_join(threads[i], NULL); } sem_destroy(&sem); // 销毁信号量 return 0; } ``` 在上面的例子中,我们创建了多个线程,每个线程都会访问共享资源 shared_resource。为了避免多个线程同时访问该资源,我们使用了一个信号量 sem,只有获得了该信号量的线程才能访问 shared_resource。在每个线程访问 shared_resource 之前,它会调用 sem_wait() 等待信号量,表示它要访问 shared_resource 了。在访问完 shared_resource 后,线程会调用 sem_post() 释放信号量,表示它已经访问完了 shared_resource,其他线程可以开始访问了。 需要注意的是,在上面的例子中,我们使用了互斥信号量,即 sem 的初始值为 1。这意味着同一时刻只有一个线程可以访问 shared_resource。如果想要多个线程同时访问 shared_resource,可以使用非互斥信号量,即将 sem 的初始值设置为大于 1 的值。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值