您的位置:首页 > 移动开发 > Objective-C

信号两及其相关函数

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.c
createstwo new threads, both of which increment a globalvariable called
count
exactly
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.c
and 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
count
starts at 0, and both threadsincrement it
NITER
times, we should see count equalto
2*NITER
at 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
count
in 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 1Thread 2data
a = data;---
0
a = a+1;---
0
---
b = data;  // 00
---
b = b + 1;0
data = a;  // 1---
1
---
data = b;  // 11
So data could end up +1, 0, -1, and there is NO WAY toknow which value! It is completely non-deterministic!

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, use

sem_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 1Thread 2data
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.]
Exercise 2.Use the example above as a guide to fix the program
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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息