SYNOPSIS
#include <semaphore.h>
int sem_init(sem_t *sem, int pshared, unsigned int value);
//初始化信号量
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 * sval);
int sem_destroy(sem_t * sem);
//注销信号量,在linux中其本质是没有任何作用的,它不做任何事情。
DESCRIPTION
This manual page documents POSIX 1003.1b semaphores, not to be confused with SystemV semaphores as described in ipc(5),
semctl(2) and semop(2).
Semaphores are counters for resources shared between threads. The basic operations on semaphores are: increment the
counter atomically, and wait until the counter is non-null and decrement it atomically.
//信号量是在多线程环境中共享资源的计数器。对信号量的基本操作无非有三个:对信号量的增加;然后阻塞线程等待,直到信号量不为空才返回;然后就是对信号量的减少。
// 在编程中,信号量最常用的方式就是一个线程A使用sem_wait阻塞,因为此时信号量计数为0,直到另外一个线程B发出信号post后,信号量计数加 1,此时,线程A得到了信号,信号量的计数为1不为空,所以就从sem_wait返回了,然后信号量的计数又减1变为零。
sem_init initializes the semaphore object pointed to by sem. The count associated with the semaphore is set initially to
value. The pshared argument indicates whether the semaphore is local to the current process ( pshared is zero) or is to
be shared between several processes ( pshared is not zero). LinuxThreads currently does not support process-shared
semaphores, thus sem_init always returns with error ENOSYS if pshared is not zero.
//在使用信号量之前,我们必须初始化信号。第三个参数通常设置为零,初始化信号的计数为0,这样第一次使用sem_wait的时候会因为信号计数为0而等待,直到在其他地方信号量post了才返回。除非你明白你在干什么,否则不要将第三个参数设置为大于0的数。
//第二个参数是用在进程之间的数据共享标志,如果仅仅使用在当前进程中,设置为0。如果要在多个进程之间使用该信号,设置为非零。但是在Linux线程中,暂时还不支持进程之间的信号共享,所以第二个参数说了半天等于白说,必须设置为0.否则将返回ENOSYS错误。
sem_wait suspends the calling thread until the semaphore pointed to by sem has non-zero count. It then atomically
decreases the semaphore count.
//当信号的计数为零的时候,sem_wait将休眠挂起当前调用线程,直到信号量计数不为零。在sem_wait返回后信号量计数将自动减1.
sem_trywait is a non-blocking variant of sem_wait. If the semaphore pointed to by sem has non-zero count, the count is
atomically decreased and sem_trywait immediately returns 0. If the semaphore count is zero, sem_trywait immediately
returns with error EAGAIN.
//sem_trywait是一个立即返回函数,不会因为任何事情阻塞。根据其返回值得到不同的信息。如果返回值为0,说明信号量在该函数调用之前大于0,但是调用之后会被该函数自动减1.至于调用之后是否为零则不得而知了。如果返回值为EAGAIN说明信号量计数为0。
sem_post atomically increases the count of the semaphore pointed to by sem. This function never blocks and can safely be
used in asynchronous signal handlers.
//解除信号量等待限制。让信号量计数加1.该函数会立即返回不等待。
sem_getvalue stores in the location pointed to by sval the current count of the semaphore sem.
//获得当前信号量计数的值。
sem_destroy destroys a semaphore object, freeing the resources it might hold. No threads should be waiting on the
semaphore at the time sem_destroy is called. In the LinuxThreads implementation, no resources are associated with
semaphore objects, thus sem_destroy actually does nothing except checking that no thread is waiting on the semaphore.
// 销毁信号量对象,释放信号量内部资源。然而在linux的线程中,其实是没有任何资源关联到信号量对象需要释放的,因此在linux中,销毁信号量对象的作用仅仅是测试是否有线程因为该信号量在等待。如果函数返回0说明没有,正常注销信号量,如果返回EBUSY,说明还有线程正在等待该信号量的信号。
CANCELLATION
sem_wait is a cancellation point.
ASYNC-SIGNAL SAFETY
On processors supporting atomic compare-and-swap (Intel 486, Pentium and later, Alpha, PowerPC, MIPS II, Motorola 68k),
the sem_post function is async-signal safe and can therefore be called from signal handlers. This is the only thread syn-
chronization function provided by POSIX threads that is async-signal safe.
On the Intel 386 and the Sparc, the current LinuxThreads implementation of sem_post is not async-signal safe by lack of
the required atomic operations.
//现在sem_post被POSIX所规范,当它改变信号量计数器值的时候是线程安全的。
RETURN VALUE
The sem_wait and sem_getvalue functions always return 0. All other semaphore functions return 0 on success and -1 on
error, in addition to writing an error code in errno.
//通常返回值往往都为0,表示成功,如果有误将返回-1,并且将错误的代码号赋值给errno。
ERRORS
The sem_init function sets errno to the following codes on error:
//sem_init失败时,常见错误有:
EINVAL value exceeds the maximal counter value SEM_VALUE_MAX
//第三个参数value值超过了系统能够承受的最大值SEM_VALUE_MAX.
ENOSYS pshared is not zero
//你将第二参数设置为了非零,如果是linux系统,请将第二个参数设置为零
The sem_trywait function sets errno to the following error code on error:
EAGAIN the semaphore count is currently 0
The sem_post function sets errno to the following error code on error:
ERANGE after incrementation, the semaphore value would exceed SEM_VALUE_MAX (the semaphore count is left unchanged
in this case)
//信号量的计数超过了系统能够承受的最大值SEM_VALUE_MAX。
The sem_destroy function sets errno to the following error code on error:
EBUSY some threads are currently blocked waiting on the semaphore.
//某些线程正在使用该信号量等待。
其实线程临界区可以使用信号量来实现,将信号量的信号初始化为1,然后在临界区使用完毕后再置信号量为1我们就可以轻松实现mutex了。
具体实现,自己慢慢琢磨一下吧。
分享到:
相关推荐
总结,这个压缩包提供了一个使用Linux信号量实现线程同步的实例,通过`sem_wait()`和`sem_post()`操作确保线程安全地访问共享资源。理解和应用这个示例可以帮助开发者深入理解多线程环境中的同步和互斥问题,提高...
`sem_init()`、`sem_post()`、`sem_wait()`、`sem_trywait()`和`sem_destroy()`是其核心函数,它们共同维护了信号量的创建、修改、检查和销毁,从而确保并发环境下的数据一致性。在实际编程中,信号量是一种强大且...
`sem_wait`函数尝试降低信号量的值,如果当前值为0,则进程会被阻塞,直到信号量值大于0。`sem_timedwait`与之类似,但增加了超时功能,若在指定时间内无法获取信号量,进程将返回失败。 4. **查询信号量值(sem_...
根据给定的代码片段及其描述,我们可以看出这是一个典型的多线程程序示例,它通过模拟一个家庭成员(父亲、母亲、儿子和女儿)之间传递水果(苹果和橙子)的过程来展示信号量(semaphore)在Linux环境下的使用方法。...
- `sem_wait()`:如果信号量值大于0,则减小信号量并返回,否则进程被阻塞。 - `sem_close()`:关闭信号量,但不删除它。 - `sem_unlink()`:删除命名信号量。 4. **信号量的使用场景** - **生产者-消费者问题*...
在Linux中,有名信号量可以通过`sem_open()`, `sem_post()`, `sem_wait()`, `sem_close()`和`sem_unlink()`等系统调用来操作。 1. **创建有名信号量**: 使用`sem_open()`函数创建有名信号量。该函数需要一个唯一...
使用`sem_wait()`函数使信号量减一。如果信号量值大于0,则进程继续执行;否则,进程被阻塞,直到其他进程调用V操作释放资源。 ```c sem_wait(&sem); // 等待信号量,如果当前值为0,则进程会被挂起 ``` 3. V...
本资源“Sem.rar”包含的是一个关于System V信号量的C语言实现,特别适用于Linux环境。System V信号量是一种同步原语,用于解决多进程间的资源访问冲突问题,确保共享数据的安全性。 首先,让我们深入理解什么是...
当一个进程请求资源时,它会尝试`sem_wait`,如果信号量值大于0,则减小信号量值并继续执行;否则,进程会被阻塞,直到其他进程释放资源,信号量值增加。 4. **进程同步**:通过在临界区前后使用`sem_wait`和`sem_...
1. **头文件**(如`sem.h`):定义了信号量相关的数据结构和函数原型,比如`sem_t`结构体以及`sem_init`、`sem_wait`、`sem_post`等函数。 2. **实现文件**(如`sem.c`):包含了上述函数的具体实现,实现了信号量...
其中,`sem_init()`函数的第一个参数是指向信号量的指针,第二个参数为0表示无名信号量,第三个参数初始化信号量的值。 ##### 2. 有名信号量 有名信号量用于进程间通信,其值保存在文件系统中,因此可以在不同进程...
`sem_open()`用于创建或打开一个信号量,`sem_close()`关闭信号量,`sem_unlink()`删除信号量,`sem_post()`增加信号量的值,而`sem_wait()`则减少信号量的值。这些函数是POSIX标准的一部分,位于 `<semaphore.h>` ...
4. **sem_wait(sem_t\* sem)**:执行wait操作,减少信号量的值或挂起当前线程直到信号量值大于零。 5. **sem_trywait(sem_t\* sem)**:尝试执行wait操作,不同于`sem_wait`,此函数不会阻塞,如果信号量值为零,则...
if(xSemaphoreTake(*sem, wait_tick) == pdTRUE) return ((xTaskGetTickCount()-start_tick)*portTICK_RATE_MS); else return SYS_ARCH_TIMEOUT; } void sys_sem_signal(sys_sem_t *sem) { if(xSemaphoreGive...
在Linux系统中,信号量通过一系列的系统调用进行操作,如`sem_init()`、`sem_post()`、`sem_wait()`和`sem_destroy()`。 1. **信号量类型与初始化**: 信号量的类型通常表示为`sem_t`,它是一个内含整型变量的数据...
例如,它可能包含了`sem_init()`、`sem_wait()`、`sem_post()`等函数的使用,这些都是POSIX标准中的信号量操作函数。 "www.pudn.com.txt"看起来像是一个文本文件,可能包含了关于这个项目的一些说明、作者信息或者...
本示例“sem.rar_linux sem_semdemo.c”提供了关于如何在Linux环境下使用信号量的详细教程,包括源代码、Makefile以及编译后的可执行文件,方便读者直接运行体验。 首先,我们要理解什么是信号量。信号量是一个整型...
`sem_init()`用于初始化信号量,`sem_wait()`用于获取信号量(若无资源,线程将被阻塞),`sem_post()`用于释放信号量(增加资源计数,唤醒等待的线程)。 下面是一个简化的C语言信号量实现生产者-消费者问题的框架...
2. **获取信号量**:在访问资源之前,调用`sem_wait`,这会尝试减小信号量的值。如果值为0,则线程或进程会被阻塞,直到其他线程或进程释放信号量。 3. **释放信号量**:在完成资源访问后,调用`sem_post`增加信号量...
3. **sem_wait**: 这个函数会尝试获取信号量。如果信号量的值大于0,它会将信号量减1并立即返回;如果值为0,那么调用的线程会被阻塞,直到其他线程调用`sem_post`增加信号量的值。成功时返回0,失败则返回-1。 ...