藍森林首頁 | 返回主頁 | 本站地圖 | 站內搜索 | 聯繫信箱 |
 您目前的位置:首頁 > 自由軟件 > 技術交流 > 應用編程


    

藍森林 http://www.lslnet.com 2006年6月6日 10:18


信號燈建立後,鎖定它沒有反應,直到我將informix關閉後才執行

//鎖定信號燈
void P(int sem_set_id)
{
        struct sembuf sem_op;

        //等待信號燈, 直到它的數值非負數
        sem_op.sem_num = 0;
        sem_op.sem_op = -1;
        sem_op.sem_flg = 0;
        semop(sem_set_id, &sem_op, 1);
    printf("鎖定信號燈");
}//end of P()

運行到semop(sem_set_id, &sem_op, 1);就沒有反映了

信號燈建立後,鎖定它沒有反應,直到我將informix關閉後才執行

你用的是什麼系統?

信號燈建立後,鎖定它沒有反應,直到我將informix關閉後才執行

sco unix 5.05

信號燈建立後,鎖定它沒有反應,直到我將informix關閉後才執行

是不是其它地方使用了這個信號燈
然後沒有釋放呢

檢查一政代碼看看

信號燈建立後,鎖定它沒有反應,直到我將informix關閉後才執行

如果是程序的其他地方調用了,不應該把INFORMIX關了就好了呀

信號燈建立後,鎖定它沒有反應,直到我將informix關閉後才執行

//建立信號燈
        sem_set_id = semget(SEM_ID, 1, IPC_CREAT | 0600);
        if (sem_set_id == -1) {
                perror("main: semget");
                exit(1);
        }

        //設置信號燈的數值是 1
        sem_val.val = 1;
        rc = semctl(sem_set_id, 0, SETVAL, sem_val);
        if (rc == -1) {
                perror("main: semctl");
                exit(1);
        }

信號燈建立後,鎖定它沒有反應,直到我將informix關閉後才執行

我懷疑你是不是沒有搞清楚信號燈是怎麼回事?
恕我冒昧,給你貼一個 demo 程序,希望對你有用:
[code]這個例子演示了信號量的一種用法, 即利用信號量實現資源的互斥訪問.

例子使用方法:
$ one & another

程序 one.c 首先建立一個信號量集合, 其中包含了一個信號量, 然後調用

        semop( semid, &FREE, 1 );

使資源可用. 接下來是一個循環處理 ---- 這是許多後台進程的典型結構 ---- 用來代表反覆的對這個資源的訪問請求. 在這個循環中, 每次訪問資源前首先使用語句

        semop( semid, &GET, 1 );

獲得對資源的使用權(注1), 然後開始訪問資源, 訪問完畢後釋放(注2).
程序 another.c 代表另外一個與 one.c 競爭使用互斥資源的進程, 它的流程與 one.c 完全相同.


注1:   這是書本中的說法, 就我理解, 該語句實際上只是將信號量的 semval 減一, 由於這兩個程序的流程的特點, 該操作也就是將 semval 置為零. 換句話說, "獲得使用權" 實際上是建立在 "自覺" 的基礎上的, 即使是你將 semval 置為零, 互斥資源仍然可以訪問.
       由於當 semval 為零時 semop( semid, &GET, 1 ) 調用將導致進程阻塞, 所以實現了 "當資源正被另一個進程使用(semval=0)時, 請求互斥使用資源的進程將等待(阻塞)".

注2:   也就是將 semval 加一, 使之可用.

總的來說, 信號量實現了一個原子性的操作, 從而使程序之間的協調變得格外容易.
[/code]
[code].c.o:
        cc -c $<

All:        TestSem clean

main:        main.o
        cc -o main main.o

TestSem:        one another

one:        one.o
        cc -o one one.o

another:        another.o
        cc -o another another.o -l curses

clean:
        if [ -f *.o ]; then rm *.o; fi

[/code]
[code]//
// filename: one.c
// writer:   flw
//

# include <unistd.h>;
# include <stdio.h>;
# include <sys/ipc.h>;
# include <sys/sem.h>;

struct sembuf GET  = { 0, -1, SEM_UNDO };
struct sembuf FREE = { 0,  1, SEM_UNDO };
struct sembuf TEST = { 0,  0, SEM_UNDO };

void main( void )
{
        int semid, ret;
        key_t key;

        key = ftok( "/", 'J' );
        if ( key == -1 )
        {
                fprintf( stderr, "Ftok() Failed!\n" );
                return;
        }

        semid = semget( key, 1, IPC_CREAT | 0666 );
        if ( semid == -1 )
        {
                fprintf( stderr, "Semget() Failed!\n" );
                return;
        }
       
        fprintf( stderr, "One Begin...\n" );

        semop( semid, &FREE, 1 );

        while(1)
        {
                semop( semid, &GET, 1 );
                fprintf( stderr, "one: 開始訪問資源!\n" );
                sleep( 1 );
                // 訪問互斥資源
                fprintf( stderr, "one: 資源訪問結束!\n" );
                semop( semid, &FREE, 1 );
                sleep( 2 );
        }
}
[/code]
[code]//
// filename: another.c
// writer:   flw
//

# include <unistd.h>;
# include <stdio.h>;
# include <sys/ipc.h>;
# include <sys/sem.h>;
# include <curses.h>;

struct sembuf TEST = { 0,  0, SEM_UNDO };
struct sembuf GET  = { 0, -1, SEM_UNDO };
struct sembuf FREE = { 0,  1, SEM_UNDO };

void main( void )
{
        int semid, ret;
        key_t key;

        key = ftok( "/", 'J' );
        if ( key == -1 )
        {
                fprintf( stderr, "Ftok() Failed!\n" );
                return;
        }

        semid = semget( key, 1, IPC_CREAT | 0666 );
        if ( semid == -1 )
        {
                fprintf( stderr, "Semget() Failed!\n" );
                return;
        }
       
        fprintf( stderr, "Another Begin...\n" );

        while(1)
        {
                sleep( 10 );
                semop( semid, &GET, 1 );
                fprintf( stderr, "another: 開始訪問資源\n" );
                // 訪問互斥資源
                sleep( 6 );
                fprintf( stderr, "another: 資源訪問結束!\n" );
                semop( semid, &FREE, 1 );
        }
}
[/code]

信號燈建立後,鎖定它沒有反應,直到我將informix關閉後才執行

我原來是不太明白信號燈的原理,但是操作系統中的P V 操作我理解和這比較相似
能不能看看我的問題出在那裡

信號燈建立後,鎖定它沒有反應,直到我將informix關閉後才執行

信號燈建立後,鎖定它沒有反應,直到我將informix關閉後才執行

沒有代碼怎麼看
檢查一下

1  semget 得到
2  semctl  設置初始值

3 semop 操作

信號燈建立後,鎖定它沒有反應,直到我將informix關閉後才執行

另外flw 給 的代碼應該好好看看

信號燈建立後,鎖定它沒有反應,直到我將informix關閉後才執行

informix 佔用了太多的sem資源,放大sem的系統配置,我好像也有過的,服務器上

信號燈建立後,鎖定它沒有反應,直到我將informix關閉後才執行

關於信號燈的轅馬如下:望各位給我看看:
//鎖定信號燈
void P(int sem_set_id)
{
        struct sembuf sem_op;

        //等待信號燈, 直到它的數值非負數
        sem_op.sem_num = 0;
        sem_op.sem_op = -1;
        sem_op.sem_flg = 0;
        semop(sem_set_id, &amp;sem_op, 1);
    printf("鎖定信號燈");
}//end of P()

//信號燈解鎖
void V(int sem_set_id)
{
        struct sembuf sem_op;

        //增加信號燈的數值
        sem_op.sem_num = 0;
        sem_op.sem_op = 1;
        sem_op.sem_flg = 0;
        semop(sem_set_id, &amp;sem_op, 1);
    printf("解鎖信號燈");
}//end of V()


int Init()
{
        int sem_set_id;            //信號燈的ID
        struct shmid_ds *ps;
        int flag = 0; // 0 --- 新建共享內存 1 --表示共享內存已存在

        union sem {
                   struct shmid_ds *ps;
                   int val;
        }sem_val;
        int rc;

        //建立信號燈
        sem_set_id = semget(SEM_ID, 1, IPC_CREAT | 0660);
        if (sem_set_id == -1) {
                perror("main: semget");
                exit(1);
        }

        //設置信號燈的數值是 1
        sem_val.val = 1;
        rc = semctl(sem_set_id, 0, SETVAL, sem_val);
        if (rc == -1) {
                perror("main: semctl");
                exit(1);
        }

        //建立field共享內存
        pScreDoc->;iShmFieldId = shmget(SHM_FIELD_ID, SHARE_FIELD_MEMORY_LEN, IPC_CREAT | IPC_EXCL | 0660);
        if (pScreDoc->;iShmFieldId == -1)
        {
                pScreDoc->;iShmFieldId = shmget(SHM_FIELD_ID, SHARE_FIELD_MEMORY_LEN, IPC_CREAT |  0660);
                    if(pScreDoc->;iShmFieldId == -1)
                    {
                        perror(" Field shmget: ");
                        exit(1);
                     };
                flag = 1;
        }//end of if
        //attach 共享內存
        pScreDoc->;shmField = (char *)shmat(pScreDoc->;iShmFieldId, NULL, 0);
        if (!pScreDoc->;shmField) {
                perror("main: shmat: ");
                exit(1);
        }//end of if
        if(1)//!flag)
        {
             printf("attach 共享內存");
               P(pScreDoc->;iShmFieldId);
                        memset(pScreDoc->;shmField,0,SHARE_FIELD_MEMORY_LEN);
                          LoadFieldLib("/usr/wuliu/screen/data/field.xml");
                       V(pScreDoc->;iShmFieldId);
        }//end of if
        flag = 0;

信號燈建立後,鎖定它沒有反應,直到我將informix關閉後才執行

我已經嘗試將系統的SEMMAP,SEMMNS SEMMNI SEMMNU SEMMSL 都放大了,還是沒有效果,請告訴我應該放大哪個,放大到多少?

信號燈建立後,鎖定它沒有反應,直到我將informix關閉後才執行

我懷疑我的問題就是系統SEM參數有問題,但是我放大了也沒有用,都已經放大到系統認可的最大值好幾倍了

信號燈建立後,鎖定它沒有反應,直到我將informix關閉後才執行

我頂

信號燈建立後,鎖定它沒有反應,直到我將informix關閉後才執行

各位高手幫幫忙,看看我的問題



Copyright © 1999-2000 LSLNET.COM. All rights reserved. 藍森林網站 版權所有。 E-mail : webmaster@lslnet.com