信号两及其相关函数
2011-10-17 23:41
323 查看
转载自:http://www.csc.villanova.edu/~mdamian/threads/posixsem.html#wait
Synchronizing Threads with POSIX Semaphores
Why semaphores?Posix semaphores are easy to use
sem_init
sem_wait
sem_post
sem_getvalue
sem_destroy
Exercises 1 2 3
Now it is time to take a look at some code that does something a littleunexpected. The program
threadadd.ccreatestwo new threads, both of which increment a globalvariable called
countexactly
NITER, with
NITER = 1,000,000.But the program produces unexpected results.
Exercise 1. Create a directory called
posixsem in your class Unix directory. Download in this directory the code
threadadd.cand compile it using
gcc threadadd.c -o threadadd -lpthread
Run the executable threadadd and observe the ouput. Try it on both tanner and
felix.
Quite unexpected! Since
countstarts at 0, and both threadsincrement it
NITERtimes, we should see count equalto
2*NITERat the end of the program. Something fishy is going on here.
Threads can greatly simplify writing elegant and efficient programs. However,there are problems when multiple threads share a common addressspace, like the variable
countin our earlier example.
To understand what might happen, let us analyze this simple piece of code:
THREAD 1 THREAD 2 a = data; b = data; a++; b--; data = a; data = b;
Now if this code is executed serially (for instance, THREAD 1 first and then
THREAD 2),there are no problems. However threads execute in an arbitrary order, so consider the following situation:
Thread 1 | Thread 2 | data |
a = data; | --- | 0 |
a = a+1; | --- | 0 |
--- | b = data; // 0 | 0 |
--- | b = b + 1; | 0 |
data = a; // 1 | --- | 1 |
--- | data = b; // 1 | 1 |
The solution to this is to provide functions that will block a threadif another thread is accessing data that it is using.
Pthreads may use semaphores to achieve this.
Posix semaphores
All POSIX semaphore functions and types are prototyped or defined insemaphore.h. To define a semaphore object, usesem_t sem_name;
To initialize a semaphore, use sem_init():
int sem_init(sem_t *sem, int pshared, unsigned int value);
sem points to a semaphore object to initialize
pshared is a flag indicating whether or not the semaphore should be shared with fork()ed processes. LinuxThreads does not currently support shared semaphores
value is an initial value to set the semaphore to
Example of use:
sem_init(&sem_name, 0, 10);
To wait on a semaphore, use sem_wait:
int sem_wait(sem_t *sem);
Example of use:
sem_wait(&sem_name);
If the value of the semaphore is negative, the calling process blocks; one of the blocked processes wakes up when another process calls
sem_post.
To increment the value of a semaphore, use sem_post:
int sem_post(sem_t *sem);
Example of use:
sem_post(&sem_name);
It increments the value of the semaphore and wakes up a blocked process waiting on the semaphore, if any.
To find out the value of a semaphore, use
int sem_getvalue(sem_t *sem, int *valp);
gets the current value of sem and places it in the location pointed to by
valp
Example of use:
int value; sem_getvalue(&sem_name, &value); printf("The value of the semaphors is %d\n", value);
To destroy a semaphore, use
int sem_destroy(sem_t *sem);
destroys the semaphore; no threads should be waiting on the semaphore if its destruction is to succeed.
Example of use:
sem_destroy(&sem_name);
Using semaphores - a short example
Consider the problem we had before and now let us use semaphores:Declare the semaphore global (outside of any funcion): sem_t mutex; Initialize the semaphore in the main function: sem_init(&mutex, 0, 1);
Thread 1 | Thread 2 | data |
sem_wait (&mutex); | --- | 0 |
--- | sem_wait (&mutex); | 0 |
a = data; | /* blocked */ | 0 |
a = a+1; | /* blocked */ | 0 |
data = a; | /* blocked */ | 1 |
sem_post (&mutex); | /* blocked */ | 1 |
/* blocked */ | b = data; | 1 |
/* blocked */ | b = b + 1; | 1 |
/* blocked */ | data = b; | 2 |
/* blocked */ | sem_post (&mutex); | 2 |
[data is fine. The data race is gone.] |
threadadd.c, so thatthe program always
produces the expected output (the value 2*NITER).
To compile a program that uses pthreads and posix semaphores, use
gcc -o filename filename.c -lpthread -lrt
相关文章推荐
- cdev结构体及其相关函数 【转】
- 网络驱动移植之sk_buff结构体及其相关操作函数(上)
- Linux内核中的jiffies及其作用介绍及jiffies等相关函数详解
- 【CSAPP读书笔记】过程及其相关操作的分析(经典:包括函数调用过程详解)
- 关于container_of和list_for_each_entry 及其相关函数的分析
- map及其相关函数的用法
- 网络驱动移植之sk_buff结构体及其相关操作函数
- pthread_mutexattr_t设置的相关函数及其说明
- C语言中操作进程信号的相关函数使用详解
- C语言中进程信号集的相关操作函数详解
- Oracle group by及其若干相关函数的一些说明
- bs_t结构及其相关函数的定义
- Linux内核中的jiffies及其作用介绍及jiffies等相关函数详解
- 关于container_of和list_for_each_entry 及其相关函数的分析
- 关于container_of和list_for_each_entry 及其相关函数的分析
- matlab中的随机矩阵及其相关函数的使用
- Oracle group by及其若干相关函数的一些说明
- bs_t结构及其相关函数的定义
- 网络驱动移植之net_device结构体及其相关的操作函数
- Clojure中Vector和List的区别及其相关函数