免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
C++通過信號量控制共享內(nèi)存的讀寫
作者:qiyuefeng11 博客  發(fā)布日期:2012-09-06 09:06:35
我來說兩句(0)
0
Tag標簽:信號量  共享內(nèi)存
信號量函數(shù)定義如下:
#include <sys/sem.h>
int semctl(int sem_id, int sem_num, int command, ...);
int semget(key_t key, int num_sems, int sem_flags);
int semop(int sem_id, struct sembuf *sem_ops, size_t num_sem_ops);
semop
函數(shù)semop用來改變信號量的值:
int semop(int sem_id, struct sembuf *sem_ops, size_t num_sem_ops);
第一個參數(shù),sem_id,是由semget函數(shù)所返回的信號量標識符。第二個參數(shù),sem_ops,是一個指向結(jié)構(gòu)數(shù)組的指針,其中的每一個結(jié)構(gòu)至少包含下列成員:
struct sembuf {
short sem_num;
short sem_op;
short sem_flg;
}
第一個成員,sem_num,是信號量數(shù)目,通常為0,除非我們正在使用一個信號量數(shù)組。sem_op成員是信號量的變化量值。(我們可以以任何量改變信號量值,而不只是1)通常情況下中使用兩個值,-1是我們的P操作,用來等待一個信號量變得可用,而+1是我們的V操作,用來通知一個信號量可用。
最后一個成員,sem_flg,通常設置為SEM_UNDO。這會使得操作系統(tǒng)跟蹤當前進程對信號量所做的改變,而且如果進程終止而沒有釋放這個信號量,如果信號量為這個進程所占有,這個標記可以使得操作系統(tǒng)自動釋放這個信號量。將sem_flg設置為SEM_UNDO是一個好習慣,除非我們需要不同的行為。如果我們確實變我們需要一個不同的值而不是SEM_UNDO,一致性是十分重要的,否則我們就會變得十分迷惑,當我們的進程退出時,內(nèi)核是否會嘗試清理我們的信號量。
semop的所用動作會同時作用,從而避免多個信號量的使用所引起的競爭條件。我們可以在手冊頁中了解關(guān)于semop處理更為詳細的信息。
www.it165.net
semctl
semctl函數(shù)允許信號量信息的直接控制:
int semctl(int sem_id, int sem_num, int command, ...);
第一個參數(shù),sem_id,是由semget所獲得的信號量標識符。sem_num參數(shù)是信號量數(shù)目。當我們使用信號量數(shù)組時會用到這個參數(shù)。通常,如果這是第一個且是唯一的一個信號量,這個值為0。command參數(shù)是要執(zhí)行的動作,而如果提供了額外的參數(shù),則是unionsemun,根據(jù)X/OPEN 規(guī)范,這個參數(shù)至少包括下列參數(shù):
union semun {
int val;
struct semid_ds *buf;
unsigned short *array;
}
許多版本的Linux在頭文件(通常為sem.h)中定義了semun聯(lián)合,盡管X/Open確認說我們必須定義我們自己的聯(lián)合。如果我們發(fā)現(xiàn)我們確實需要定義我們自己的聯(lián)合,我們可以查看semctl手冊頁了解定義。如果有這樣的情況,建議使用手冊頁中提供的定義,盡管這個定義與上面的有區(qū)別。
有多個不同的command值可以用于semctl。在這里我們描述兩個會經(jīng)常用到的值。要了解semctl功能的詳細信息,我們應該查看手冊頁。
這兩個通常的command值為:
SETVAL:用于初始化信號量為一個已知的值。所需要的值作為聯(lián)合semun的val成員來傳遞。在信號量第一次使用之前需要設置信號量。
IPC_RMID:當信號量不再需要時用于刪除一個信號量標識。
semctl函數(shù)依據(jù)command參數(shù)會返回不同的值。對于SETVAL與IPC_RMID,如果成功則會返回0,否則會返回-1。
信號量與共享內(nèi)存的共同使用例子:
write 端:
view sourceprint?
01.#include <stdio.h>
02.#include <stdlib.h>
03.#include <string.h>
04.#include <sys/types.h>
05.#include <sys/ipc.h>
06.#include <sys/shm.h>
07.#include <errno.h>
08.#include "sem.h"
09.
10.typedef struct
11.{
12.char buf[1024];
13.}memory;
14.
15.int main(int argc, const char *argv[])
16.{
17.key_t key;
18.memory *p = NULL;
19.int shmid;
20.int create_flag = 0;
21.int sem_id;
22.if ((key = ftok(".", 'a')) < 0)
23.{
24.perror("failed to get key");
25.exit(-1);
26.}
27.
28.if ((sem_id = semget(key, 1, 0666 | IPC_CREAT | IPC_EXCL)) < 0)
29.{
30.if (errno == EEXIST)
31.{
32.if ((sem_id = semget(key, 1, 0666)) < 0)
33.{
34.perror("failed to semget");
35.exit(-1);
36.}
37.}
38.}
39.
40.init_sem(sem_id, 0);
41.if ((shmid = shmget(key, sizeof(memory), 0666 | IPC_CREAT | IPC_EXCL)) < 0)
42.{
43.if (errno == EEXIST)
44.{
45.if ((shmid = shmget(key, sizeof(memory), 0666)) < 0)
46.{
47.perror("failed to shmget memory");
48.exit(-1);
49.}
50.}
51.else
52.{
53.perror("failed to shmget");
54.exit(-1);
55.}
56.}
57.else
58.create_flag = 1;
59.if ((p = shmat(shmid, NULL, 0)) == (void *)(-1))
60.{
61.perror("failed to shmat memory");
62.exit(-1);
63.}
64.while(1)
65.{
66.printf(">");
67.fgets(p->buf, sizeof(p->buf), stdin);
68.p->buf[strlen(p->buf) - 1] = 0;
69.sem_v(sem_id);
70.if (strncmp(p->buf, "quit", 4) == 0)
71.break;
72.}
73.
74.if (create_flag == 1)
75.{
76.if (shmdt(p) < 0)
77.{
78.perror("failed to shmdt memory");
79.exit(-1);
80.}
81.
82.if (shmctl(shmid, IPC_RMID, NULL) == -1)
83.{
84.perror("failed to delete share memory");
85.exit(-1);
86.}
87.delete_sem(sem_id);
88.}
89.return 0;
90.}
read 端:
view sourceprint?
01.#include <stdio.h>
02.#include <stdlib.h>
03.#include <string.h>
04.#include <sys/types.h>
05.#include <sys/ipc.h>
06.#include <sys/shm.h>
07.#include <errno.h>
08.#include "sem.h"
09.
10.typedef struct
11.{
12.char buf[1024];
13.}memory;
14.
15.int main(int argc, const char *argv[])
16.{
17.key_t key;
18.int shmid;
19.memory *p = NULL;
20.int create_flag = 0;
21.int sem_id;
22.if ((key = ftok(".", 'a')) < 0)
23.{
24.perror("failed to get key");
25.exit(-1);
26.}
27.if ((sem_id = semget(key, 1, 0666 | IPC_CREAT | IPC_EXCL)) < 0)
28.{
29.if (errno == EEXIST)
30.{
31.if ((sem_id = semget(key, 1, 0666)) < 0)
32.{
33.perror("failed to semget");
34.exit(-1);
35.}
36.}
37.}
38.init_sem(sem_id, 0);
39.
40.if ((shmid = shmget(key, sizeof(memory), 0666 | IPC_CREAT | IPC_EXCL)) < 0)
41.{
42.if (errno == EEXIST)
43.{
44.if ((shmid = shmget(key, sizeof(memory), 0666)) < 0)
45.{
46.perror("failed to create share memory");
47.exit(-1);
48.}
49.}
50.else
51.{
52.perror("failed to shmget");
53.exit(-1);
54.}
55.}
56.else
57.create_flag = 1;
58.
59.if ((p = shmat(shmid, NULL, 0)) == (void *)(-1))
60.{
61.perror("failed to shmat");
62.exit(-1);
63.}
64.
65.while(1)
66.{
67.sem_p(sem_id);
68.if (strncmp(p->buf, "quit", 4) == 0)
69.break;
70.printf("recv: %s\n", p->buf);
71.
72.}
73.
74.if (create_flag == 1)
75.{
76.if (shmdt(p) < 0)
77.{
78.perror("failed to shmdt");
79.exit(-1);
80.}
81.
82.if (shmctl(shmid, IPC_RMID, NULL) == -1)
83.{
84.perror("failed to delete share memory");
85.exit(-1);
86.}
87.delete_sem(sem_id);
88.}
89.return 0;
90.}
信號量的封裝:
view sourceprint?
01.#include <stdio.h>
02.#include <stdlib.h>
03.#include <sys/types.h>
04.#include <sys/ipc.h>
05.#include <sys/sem.h>
06.#include <unistd.h>
07.
08.void init_sem(int , int );
09.void delete_sem(int );
10.void sem_p(int );
11.void sem_v(int );
12.
13.union semun
14.{
15.int val;
16.struct semid_ds *buf;
17.unsigned short *array;
18.};
19.
20.void init_sem(int sem_id, int init_value)
21.{
22.union semun sem_union;
23.sem_union.val = init_value;
24.
25.if (semctl(sem_id, 0, SETVAL, sem_union) < 0)
26.{
27.perror("failed to init_sem");
28.exit(-1);
29.}
30.return ;
31.}
32.
33.void delete_sem(int sem_id)
34.{
35.union semun sem_union;
36.if (semctl(sem_id, 0, IPC_RMID, sem_union) < 0)
37.{
38.perror("failed to delete_sem");
39.exit(-1);
40.}
41.return ;
42.}
43.void sem_p(int sem_id)
44.{
45.struct sembuf sem_b;
46.sem_b.sem_num = 0;
47.sem_b.sem_op = -1;
48.sem_b.sem_flg = SEM_UNDO;
49.if (semop(sem_id, &sem_b, 1) < 0)
50.{
51.perror("failed to sem_p");
52.exit(-1);
53.}
54.return;
55.}
56.void sem_v(int sem_id)
57.{
58.struct sembuf sem_b;
59.sem_b.sem_num = 0;
60.sem_b.sem_op = 1;
61.sem_b.sem_flg = SEM_UNDO;
62.
63.if (semop(sem_id, &sem_b, 1) < 0)
64.{
65.perror("failed to sem_v");
66.exit(-1);
67.}
68.return ;
69.}
本站僅提供存儲服務,所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
多進程之信號量 Linux函數(shù) semget();semctl();semop(); [轉(zhuǎn)]
Linux System V信號量&POSIX信號量區(qū)別
linux信號量_閑の洎茬
進程間通信(IPC):共享內(nèi)存(shared memory)和信號量(semaphore)
【linux草鞋應用編程系列】
獲取信號量信息 利用信號量實現(xiàn)共享資源的申請和釋放
更多類似文章 >>
生活服務
分享 收藏 導長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服