Cobalt/POSIX 信号量服务。
信号量是在线程之间共享资源的计数器。信号量的基本操作是:原子性地增加计数器,以及等待计数器为非零并原子性地减少它。
信号量有一个最大值,超过该值后不能再增加。宏 SEM_VALUE_MAX 被定义为此最大值。
int sem_close (sem_t *sem)
关闭命名信号量。
此服务关闭信号量 sem。信号量仅在调用 sem_unlink() 服务取消链接并且每次调用 sem_open() 都匹配一次此服务调用时才会被销毁。
当信号量被销毁时,它使用的内存将返回到系统堆,因此进一步引用此信号量不保证失败,这与未命名信号量的情况相同。
如果 sem 是未命名信号量,则此服务将失败。
参数:
返回值:
errno:
标签:
thread-unrestricted,switch-secondary示例代码
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include <fcntl.h>
#include <unistd.h>
#define NUM_THREADS 5
#define SEM_NAME "/my_semaphore"
sem_t *sem;
void *thread_function(void *arg) {
int thread_id = *((int *)arg);
// 请求访问信号量
sem_wait(sem);
// 访问共享资源
printf("Thread %d: has entered the critical section.\n", thread_id);
sleep(1); // 模拟对共享资源的处理
printf("Thread %d: is leaving the critical section.\n", thread_id);
// 释放信号量
sem_post(sem);
return NULL;
}
int main() {
pthread_t threads[NUM_THREADS];
int thread_ids[NUM_THREADS];
// 创建信号量,初始值为1
sem = sem_open(SEM_NAME, O_CREAT, 0644, 1);
if (sem == SEM_FAILED) {
perror("sem_open failed");
exit(EXIT_FAILURE);
}
// 创建多个线程
for (int i = 0; i < NUM_THREADS; i++) {
thread_ids[i] = i + 1;
pthread_create(&threads[i], NULL, thread_function, &thread_ids[i]);
}
// 等待所有线程完成
for (int i = 0; i < NUM_THREADS; i++) {
pthread_join(threads[i], NULL);
}
// 关闭信号量
if (sem_close(sem) == -1) {
perror("sem_close failed");
}
// 删除信号量
if (sem_unlink(SEM_NAME) == -1) {
perror("sem_unlink failed");
}
return 0;
}
int sem_destroy (sem_t *sem)
销毁未命名信号量。
此服务销毁信号量 sem。当前阻塞在 sem 上的线程将被解除阻塞,并且它们调用的服务将返回 -1,并将 errno 设置为 EINVAL。然后,信号量被所有信号量服务视为无效(它们都将失败并将 errno 设置为 EINVAL),除了 sem_init()。
如果 sem 是命名信号量,则此服务将失败。
参数:
返回值:
成功时总是返回 0。
sem_init_np() 中提到了 SEM_WARNDEL,则信号量按请求删除,并返回一个严格的正值以警告调用者是否有线程在等待,否则返回零。sem_init_np() 中提到了 SEM_NOBUSYDEL,则 sem_destroy() 仅在没有线程等待信号量删除时才可能成功;否则返回 -EBUSY。如果出错,返回 -1 并设置 errno:
标签:
thread-unrestricted示例代码
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>
#define NUM_THREADS 5
sem_t semaphore;
void *thread_function(void *arg) {
int thread_id = *((int *)arg);
// 请求访问信号量
sem_wait(&semaphore);
// 访问共享资源
printf("Thread %d: has entered the critical section.\n", thread_id);
sleep(1); // 模拟对共享资源的处理
printf("Thread %d: is leaving the critical section.\n", thread_id);
// 释放信号量
sem_post(&semaphore);
return NULL;
}
int main() {
pthread_t threads[NUM_THREADS];
int thread_ids[NUM_THREADS];
// 初始化信号量,初始值为2(表示可以有两个线程进入临界区)
if (sem_init(&semaphore, 0, 2) != 0) {
perror("sem_init failed");
exit(EXIT_FAILURE);
}
// 创建多个线程
for (int i = 0; i < NUM_THREADS; i++) {
thread_ids[i] = i + 1;
pthread_create(&threads[i], NULL, thread_function, &thread_ids[i]);
}
// 等待所有线程完成
for (int i = 0; i < NUM_THREADS; i++) {
pthread_join(threads[i], NULL);
}
// 销毁信号量
if (sem_destroy(&semaphore) != 0) {
perror("sem_destroy failed");
}
return 0;
}
int sem_init (sem_t *sem, int pshared, unsigned int value)
初始化未命名信号量。
此服务初始化信号量 sem,初始值为 value。
如果 sem 已经初始化或是命名信号量,则此服务将失败。
参数:
sem_init() 的线程所在的同一进程中的线程使用;如果为非零,表示新信号量可以被任何有权访问信号量所在内存的线程使用。返回值:
errno:
CONFIG_XENO_OPT_SHARED_HEAPSZ,对于进程私有信号量,请增加 CONFIG_XENO_OPT_PRIVATE_HEAPSZ;CONFIG_XENO_OPT_REGISTRY_NRSLOTS;SEM_VALUE_MAX。标签:
thread-unrestricted示例代码
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>
#define NUM_THREADS 5
sem_t semaphore;
void *thread_function(void *arg) {
int thread_id = *((int *)arg);
// 请求访问信号量
sem_wait(&semaphore);
// 访问共享资源
printf("Thread %d: has entered the critical section.\n", thread_id);
sleep(1); // 模拟对共享资源的处理
printf("Thread %d: is leaving the critical section.\n", thread_id);
// 释放信号量
sem_post(&semaphore);
return NULL;
}
int main() {
pthread_t threads[NUM_THREADS];
int thread_ids[NUM_THREADS];
// 初始化信号量,初始值为2(表示可以有两个线程进入临界区)
if (sem_init(&semaphore, 0, 2) != 0) {
perror("sem_init failed");
exit(EXIT_FAILURE);
}
// 创建多个线程
for (int i = 0; i < NUM_THREADS; i++) {
thread_ids[i] = i + 1;
pthread_create(&threads[i], NULL, thread_function, &thread_ids[i]);
}
// 等待所有线程完成
for (int i = 0; i < NUM_THREADS; i++) {
pthread_join(threads[i], NULL);
}
// 销毁信号量
if (sem_destroy(&semaphore) != 0) {
perror("sem_destroy failed");
}
return 0;
}
int sem_post (sem_t *sem)
释放信号量。
此服务释放信号量 sem。
如果当前没有线程阻塞在此信号量上,并且未启用“脉冲”模式(参见 sem_init_np(),SEM_PULSE),则其计数将增加。如果有线程阻塞在信号量上,则等待队列中的第一个线程将被解除阻塞。
参数:
返回值:
errno:
SEM_VALUE_MAX。标签:
unrestricted示例代码
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include <fcntl.h>
#include <unistd.h>
#define NUM_THREADS 5
#define SEM_NAME "/my_semaphore"
sem_t *sem;
void *thread_function(void *arg) {
int thread_id = *((int *)arg);
// 请求访问信号量
sem_wait(sem);
// 访问共享资源
printf("Thread %d: has entered the critical section.\n", thread_id);
sleep(1); // 模拟对共享资源的处理
printf("Thread %d: is leaving the critical section.\n", thread_id);
// 释放信号量
sem_post(sem);
return NULL;
}
int main() {
pthread_t threads[NUM_THREADS];
int thread_ids[NUM_THREADS];
// 创建信号量,初始值为1
sem = sem_open(SEM_NAME, O_CREAT, 0644, 1);
if (sem == SEM_FAILED) {
perror("sem_open failed");
exit(EXIT_FAILURE);
}
// 创建多个线程
for (int i = 0; i < NUM_THREADS; i++) {
thread_ids[i] = i + 1;
pthread_create(&threads[i], NULL, thread_function, &thread_ids[i]);
}
// 等待所有线程完成
for (int i = 0; i < NUM_THREADS; i++) {
pthread_join(threads[i], NULL);
}
// 关闭信号量
if (sem_close(sem) == -1) {
perror("sem_close failed");
}
// 删除信号量
if (sem_unlink(SEM_NAME) == -1) {
perror("sem_unlink failed");
}
return 0;
}
int sem_trywait (sem_t *sem)
尝试减少信号量。
此服务等同于 sem_wait(),但如果信号量 sem 当前已耗尽,它会立即返回,并且它不是一个取消点。
参数:
返回值:
errno:
标签:
xthread-only示例代码
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include <fcntl.h>
#include <unistd.h>
#define NUM_THREADS 5
#define SEM_NAME "/my_semaphore"
sem_t *sem;
void *thread_function(void *arg) {
int thread_id = *((int *)arg);
// 请求访问信号量
while(sem_trywait(sem) != 0) {
sleep(1);
}
// 访问共享资源
printf("Thread %d: has entered the critical section.\n", thread_id);
sleep(1); // 模拟对共享资源的处理
printf("Thread %d: is leaving the critical section.\n", thread_id);
// 释放信号量
sem_post(sem);
return NULL;
}
int main() {
pthread_t threads[NUM_THREADS];
int thread_ids[NUM_THREADS];
// 创建信号量,初始值为1
sem = sem_open(SEM_NAME, O_CREAT, 0644, 1);
if (sem == SEM_FAILED) {
perror("sem_open failed");
exit(EXIT_FAILURE);
}
// 创建多个线程
for (int i = 0; i < NUM_THREADS; i++) {
thread_ids[i] = i + 1;
pthread_create(&threads[i], NULL, thread_function, &thread_ids[i]);
}
// 等待所有线程完成
for (int i = 0; i < NUM_THREADS; i++) {
pthread_join(threads[i], NULL);
}
// 关闭信号量
if (sem_close(sem) == -1) {
perror("sem_close failed");
}
// 删除信号量
if (sem_unlink(SEM_NAME) == -1) {
perror("sem_unlink failed");
}
return 0;
}
int sem_unlink (const char *name)
取消命名信号量的链接。
此服务取消名为 name 的信号量的链接。该信号量在通过调用 sem_close() 关闭所有通过 sem_open() 获取的引用之前不会被销毁。然而,取消链接的信号量将无法再通过 sem_open() 服务访问。
当信号量被销毁时,它使用的内存将返回到系统堆,因此进一步引用此信号量不保证失败,这与未命名信号量的情况相同。
参数:
返回值:
errno:
标签:
thread-unrestricted,switch-secondary示例代码
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include <fcntl.h>
#include <unistd.h>
#define NUM_THREADS 5
#define SEM_NAME "/my_semaphore"
sem_t *sem;
void *thread_function(void *arg) {
int thread_id = *((int *)arg);
// 请求访问信号量
sem_wait(sem);
// 访问共享资源
printf("Thread %d: has entered the critical section.\n", thread_id);
sleep(1); // 模拟对共享资源的处理
printf("Thread %d: is leaving the critical section.\n", thread_id);
// 释放信号量
sem_post(sem);
return NULL;
}
int main() {
pthread_t threads[NUM_THREADS];
int thread_ids[NUM_THREADS];
// 创建信号量,初始值为1
sem = sem_open(SEM_NAME, O_CREAT, 0644, 1);
if (sem == SEM_FAILED) {
perror("sem_open failed");
exit(EXIT_FAILURE);
}
// 创建多个线程
for (int i = 0; i < NUM_THREADS; i++) {
thread_ids[i] = i + 1;
pthread_create(&threads[i], NULL, thread_function, &thread_ids[i]);
}
// 等待所有线程完成
for (int i = 0; i < NUM_THREADS; i++) {
pthread_join(threads[i], NULL);
}
// 关闭信号量
if (sem_close(sem) == -1) {
perror("sem_close failed");
}
// 删除信号量
if (sem_unlink(SEM_NAME) == -1) {
perror("sem_unlink failed");
}
return 0;
}
int sem_wait(sem_t *sem)
减少信号量。
此服务在信号量 sem 的当前值大于 0 时减少其值。如果信号量的当前值为零,则调用线程将被挂起,直到信号量被释放,或者一个信号被传递给调用线程。
对于通过 pthread_create() 服务创建的 Cobalt 线程,此服务是一个取消点。当这样的线程在调用此服务时被取消时,在调用取消清理处理程序之前,信号量状态保持不变。
参数:
返回值:
errno:
标签:
xthread-only,switch-primary示例代码
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include <fcntl.h>
#include <unistd.h>
#define NUM_THREADS 5
#define SEM_NAME "/my_semaphore"
sem_t *sem;
void *thread_function(void *arg) {
int thread_id = *((int *)arg);
// 请求访问信号量
sem_wait(sem);
// 访问共享资源
printf("Thread %d: has entered the critical section.\n", thread_id);
sleep(1); // 模拟对共享资源的处理
printf("Thread %d: is leaving the critical section.\n", thread_id);
// 释放信号量
sem_post(sem);
return NULL;
}
int main() {
pthread_t threads[NUM_THREADS];
int thread_ids[NUM_THREADS];
// 创建信号量,初始值为1
sem = sem_open(SEM_NAME, O_CREAT, 0644, 1);
if (sem == SEM_FAILED) {
perror("sem_open failed");
exit(EXIT_FAILURE);
}
// 创建多个线程
for (int i = 0; i < NUM_THREADS; i++) {
thread_ids[i] = i + 1;
pthread_create(&threads[i], NULL, thread_function, &thread_ids[i]);
}
// 等待所有线程完成
for (int i = 0; i < NUM_THREADS; i++) {
pthread_join(threads[i], NULL);
}
// 关闭信号量
if (sem_close(sem) == -1) {
perror("sem_close failed");
}
// 删除信号量
if (sem_unlink(SEM_NAME) == -1) {
perror("sem_unlink failed");
}
return 0;
}