LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 1235|回复: 5

請問有沒有實現 semaphore 簡單的例子??

[复制链接]
发表于 2007-5-21 07:50:11 | 显示全部楼层 |阅读模式
請問有沒有實現 semaphore 簡單的例子??
发表于 2007-5-21 07:56:26 | 显示全部楼层
beginning linux programming这本书里面有
回复 支持 反对

使用道具 举报

 楼主| 发表于 2007-5-21 15:55:38 | 显示全部楼层
Post by Tinow
beginning linux programming这本书里面有


可否將例子登出來看看
回复 支持 反对

使用道具 举报

发表于 2007-5-21 17:40:03 | 显示全部楼层
Try It Out—Semaphores
1. After the #includes, the function prototypes, and the global variable, we come to the main
function. There the semaphore is created with a call to semget, which returns the semaphore
ID. If the program is the first to be called (i.e., it’s called with a parameter and argc > 1),
a call is made to set_semvalue to initialize the semaphore and op_char is set to X.
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include “semun.h”
static int set_semvalue(void);
static void del_semvalue(void);
static int semaphore_p(void);
static int semaphore_v(void);
static int sem_id;
int main(int argc, char *argv[])
{
int i;
int pause_time;
char op_char = ‘O’;
srand((unsigned int)getpid());
sem_id = semget((key_t)1234, 1, 0666 | IPC_CREAT);
if (argc > 1) {
if (!set_semvalue()) {
fprintf(stderr, “Failed to initialize semaphore\n”);
exit(EXIT_FAILURE);
}
op_char = ‘X’;
sleep(2);
}
2. Then we have a loop that enters and leaves the critical section 10 times. There we first make a
call to semaphore_p, which sets the semaphore to wait as this program is about to enter the
critical section.
for(i = 0; i < 10; i++) {
if (!semaphore_p()) exit(EXIT_FAILURE);
printf(“%c”, op_char);fflush(stdout);
pause_time = rand() % 3;
sleep(pause_time);
printf(“%c”, op_char);fflush(stdout);
3. After the critical section, we call semaphore_v, setting the semaphore as available, before
going through the for loop again after a random wait. After the loop, the call to del_semvalue
is made to clean up the code.
if (!semaphore_v()) exit(EXIT_FAILURE);
pause_time = rand() % 2;
sleep(pause_time);
}
printf(“\n%d - finished\n”, getpid());
if (argc > 1) {
sleep(10);
del_semvalue();
}
exit(EXIT_SUCCESS);
}
4. The function set_semvalue initializes the semaphore using the SETVAL command in a
semctl call. We need to do this before we can use the semaphore:
static int set_semvalue(void)
{
union semun sem_union;
sem_union.val = 1;
if (semctl(sem_id, 0, SETVAL, sem_union) == -1) return(0);
return(1);
}
5. The del_semvalue function has almost the same form, except that the call to semctl uses
the command IPC_RMID to remove the semaphore’s ID:
static void del_semvalue(void)
{
union semun sem_union;
if (semctl(sem_id, 0, IPC_RMID, sem_union) == -1)
fprintf(stderr, “Failed to delete semaphore\n”);
}
6. semaphore_p changes the semaphore by –1 (waiting):
static int semaphore_p(void)
{
struct sembuf sem_b;
sem_b.sem_num = 0;
sem_b.sem_op = -1; /* P() */
sem_b.sem_flg = SEM_UNDO;
if (semop(sem_id, &sem_b, 1) == -1) {
fprintf(stderr, “semaphore_p failed\n”);
return(0);
}
return(1);
}
7. semaphore_v is similar except for setting the sem_op part of the sembuf structure to 1, so that
the semaphore becomes available.
static int semaphore_v(void)
{
struct sembuf sem_b;
sem_b.sem_num = 0;
sem_b.sem_op = 1; /* V() */
sem_b.sem_flg = SEM_UNDO;
if (semop(sem_id, &sem_b, 1) == -1) {
fprintf(stderr, “semaphore_v failed\n”);
return(0);
}
return(1);
}
Notice that this simple program allows only a single binary semaphore per program, although we could
extend it to pass the semaphore variable if we need more semaphores. Normally, a single binary
semaphore is sufficient.
We can test our program by invoking it several times. The first time, we pass a parameter to tell the
program that it’s responsible for creating and deleting the semaphore. The other invocations have no
parameter.

Here’s some sample output, with two invocations of the program:
$ ./sem1 1 &
[1] 1082
$ ./sem1
OOXXOOXXOOXXOOXXOOXXOOOOXXOOXXOOXXOOXXXX
1083 - finished
1082 - finished
$
As you can see, the Os and Xs are properly paired, indicating that the critical section is being correctly
processed. If this doesn’t work on your particular system, you may have to use the command stty
–tostop before invoking the program to ensure that the background program generating tty output
does not cause a signal to be generated.
How It Works
The program starts by obtaining a semaphore identity from the (arbitrary) key that we’ve chosen using
the semget function. The IPC_CREAT flag causes the semaphore to be created if one is required.
If the program has a parameter, it’s responsible for initializing the semaphore, which it does with our
function set_semvalue, a simplified interface to the more general semctl function. It also uses the
presence of the parameter to determine which character it should print out. The sleep simply allows us
some time to invoke other copies of the program before this copy gets to execute too many times around
its loop. We use srand and rand to introduce some pseudo-random timing into the program.
The program then loops 10 times, with pseudo-random waits in its critical and noncritical sections.
The critical section is guarded by calls to our semaphore_p and semaphore_v functions, which are
simplified interfaces to the more general semop function.
Before it deletes the semaphore, the program that was invoked with a parameter then waits to allow
other invocations to complete. If the semaphore isn’t deleted, it will continue to exist in the system even
though no programs are using it. In real programs, it’s very important to ensure you don’t unintentionally
leave semaphores around after execution. It may cause problems next time you run the program,
and semaphores are a limited resource that you must conserve.
回复 支持 反对

使用道具 举报

 楼主| 发表于 2007-5-21 20:07:05 | 显示全部楼层
這樣複雜??
不過也謝謝..
回复 支持 反对

使用道具 举报

发表于 2007-5-21 21:49:30 | 显示全部楼层
有很多解释文字,因为太懒惰所以没把代码分开。
代码不长的
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表