用Win32汇编实现的 读者/写者,写者具有优先权 的问题

如果写者拥有优先权,用ReentrantReadWriteLock似乎不好实现,昨晚就用汇编语言写了个,程序输出结果到打开的.txt问题格式如:
01348   R      672       47
01520   R      766       16
01656   W      828       63
01800   R      907        0
第一项表示线程ID,第二项表示操作属性,第三项表示延迟时间,第四项表示操作时间,都是用Sleep函数来模拟
源程序如下:
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;writer and reader problem       
        .386
        .model flat, stdcall
        option casemap:none
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;include文件定义
include     windows.inc
include     user32.inc
includelib  user32.lib
include     kernel32.inc
includelib  kernel32.lib                            
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;equ等值定义
DLG_MAIN           equ   1000
ICO_MAIN             equ   100
IDC_READER      equ   1001
IDC_WRITER       equ   1002
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>       
;数据段
        .data
dwWriter                   dd    5                                    ;写者数量
dwReader                dd    30                                   ;读者数量  
dwWriterNumber     dd    0                                     ;当前正在写的数量                                   
dwReaderNumber     dd    0                                   ;当前正在读的数量
dwOption                    dd    1
szReaderMessage   db    '%05d   R   %6d   %6d', 0dh, 0
szWriterMessage      db    '%05d   W   %6d   %6d', 0dh, 0
   
        .data?
hInstance                    dd    ?
hReader                     dd    ?
hWriter                       dd    ?
hStart                         dd    ?
hWSemaphore         dd    ?                                    ;控制写的信号量
hWriterNumber         dd    ?                                    ;控制修改dwWriterNumber的信号量
hRSemaphore          dd    ?                                    ;读线程排队的信号量
hRSem                      dd    ?                                    ;当至少有一个写线程时,禁止所有的读线程
hReaderNumber      dd    ?                                    ;控制修改dwReaderNumber的信号量

        .const
szWriter               db    '写操作',0
szReader            db    '读操作',0       
szDestClass       db    'Notepad',0   
szStop                 db    '退出',0
szNotFound        db    '没有找到文本窗口',0
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;代码段
        .code
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   
;将运行结果在记事本窗口中显示   
_SendtoNotepad    proc    _lpsz
        local    @hDest
       
        pushad
       
        invoke    FindWindow,addr szDestClass,NULL
        .if    eax
              mov    ecx,eax
              invoke    ChildWindowFromPoint,ecx,20,20
        .endif
        .if    eax
                mov    @hDest,eax
              mov    esi,_lpsz
              @@:
              lodsb
              or    al,al
              jz    @F
              movzx    eax,al
              invoke    PostMessage,@hDest,WM_CHAR,eax,1
              jmp    @B
              @@:
        .endif
       
        popad
       
        ret
_SendtoNotepad    endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;Readter过程
_ProcReader  proc _lparam
        local     @dwThreadID
        local     @dwTickCounter1
        local     @dwTickCounter2
        local     @szBuffer[20]:byte
       
        pushad
       
        invoke    GetTickCount                                      ;获取系统时间
        mov       @dwTickCounter1, eax
                                   
        invoke    GetCurrentThreadId                           ;获取当前线程ID
        mov       @dwThreadID, eax 
        mov       ecx,  2
        xor       edx, edx
        div       ecx                                 
        invoke    Sleep,eax
 
       
        invoke    GetTickCount                                 ;得到延迟时间
        sub       eax, @dwTickCounter1
        mov       @dwTickCounter2, eax
       
        invoke    WaitForSingleObject, hRSemaphore, INFINITE
        invoke    WaitForSingleObject, hRSem, INFINITE
        invoke    WaitForSingleObject, hReaderNumber, INFINITE
                            inc  dwReaderNumber
                            .if  dwReaderNumber==1
                                    invoke WaitForSingleObject, hWSemaphore, INFINITE
                            .endif
        invoke    ReleaseSemaphore, hReaderNumber, 1, NULL                           
        invoke    ReleaseSemaphore, hRSem, 1, NULL
        invoke    ReleaseSemaphore, hRSemaphore, 1, NULL
                
    mov       eax, @dwThreadID
    mov       ecx, 100
    xor       edx, edx
    div       ecx
    invoke    Sleep, edx                                      ;在这里呆一会
   
    invoke    WaitForSingleObject, hReaderNumber, INFINITE
              dec  dwReaderNumber
              .if   dwReaderNumber == 0
                   invoke ReleaseSemaphore, hWSemaphore, 1, NULL
              .endif
    invoke    ReleaseSemaphore, hReaderNumber, 1, NULL
   
    invoke    GetTickCount                                 ;得到操作时间
    sub       eax, @dwTickCounter1
    sub       eax, @dwTickCounter2
    mov       @dwTickCounter1, eax
     invoke    wsprintf, addr @szBuffer, addr szReaderMessage,/
                @dwThreadID, @dwTickCounter2, @dwTickCounter1
    invoke    _SendtoNotepad, addr @szBuffer               
 
   
      popad
       ret
_ProcReader        endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;Writer过程
_ProcWriter     proc _lparam
        local     @dwThreadID
        local     @dwTickCounter1
        local     @dwTickCounter2
        local     @szBuffer[20]:Byte
       
        pushad
       
        invoke    GetTickCount
        mov       @dwTickCounter1, eax
       
        invoke    GetCurrentThreadId                           ;获取当前线程ID
        mov       @dwThreadID, eax
        .if       (eax&4)
                  invoke Sleep, eax
       .else
              mov ecx, 2
              xor edx, edx
              div ecx
              invoke Sleep, eax
        .endif                               
               
        invoke    WaitForSingleObject, hWriterNumber, INFINITE
        inc       dwWriterNumber
        .if       dwWriterNumber == 1
                  invoke WaitForSingleObject, hRSem, INFINITE
        .endif
        invoke    ReleaseSemaphore, hWriterNumber, 1, NULL
       
        invoke    WaitForSingleObject, hWSemaphore, INFINITE
        invoke    GetTickCount                                 ;得到延迟时间
        sub       eax, @dwTickCounter1
        mov       @dwTickCounter2, eax
        mov       eax, @dwThreadID
        mov       ecx, 100
        xor       edx, edx
        div       ecx
        invoke    Sleep, edx                                     ;在这里呆一会
       invoke    ReleaseSemaphore, hWSemaphore, 1, NULL
   
      invoke    WaitForSingleObject, hWriterNumber, INFINITE
     dec       dwWriterNumber
    .if       dwWriterNumber == 0
              invoke ReleaseSemaphore, hRSem, 1, NULL
    .endif
   
     invoke    GetTickCount                                  ;得到操作时间
    sub       eax, @dwTickCounter1
    sub       eax, @dwTickCounter2
    mov       @dwTickCounter1, eax  
     
      invoke    wsprintf, addr @szBuffer, addr szWriterMessage,/
                @dwThreadID, @dwTickCounter2, @dwTickCounter1
        invoke    _SendtoNotepad, addr @szBuffer
       
    invoke    ReleaseSemaphore, hWriterNumber, 1, NULL
   
       
        popad
        ret
_ProcWriter        endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

;对话框过程
_ProcDlgMain proc uses ebx esi edi, hWnd, wMsg, wParam, lParam
        mov eax, wMsg
        .if    eax == WM_COMMAND
                mov eax, wParam
            .if  ax == IDOK
                    .if  dwOption == 1
                        mov dwOption, 0
                   
                    invoke  GetDlgItemInt, hWnd, IDC_READER,NULL, FALSE
                    mov     dwReader, eax
                    invoke  GetDlgItemInt, hWnd, IDC_WRITER, NULL, FALSE
                    mov     dwWriter, eax
                    invoke  SetWindowText, hStart, offset szStop
               
                .while (dwWriter>0)
                                invoke CreateThread, NULL, NULL,offset _ProcWriter,/
                               NULL, NULL, NULL 
                            dec dwWriter
                    .endw
                    .while (dwReader>0)
                                    invoke CreateThread, NULL, NULL, offset _ProcReader,/
                                   NULL, NULL, NULL  
                            dec dwReader
                        .endw
                    .elseif dwOption == 0
                        invoke EndDialog, hWnd, NULL
            .endif                        
                 .endif   
       
        .elseif     eax == WM_CLOSE
                invoke  EndDialog, hWnd, NULL
        .elseif eax == WM_INITDIALOG
                invoke  LoadIcon, hInstance, ICO_MAIN
                invoke  SendMessage, hWnd, WM_SETICON, ICON_BIG, eax
               
                invoke  GetDlgItem, hWnd, IDC_READER
                mov     hReader, eax
                invoke  GetDlgItem, hWnd, IDC_WRITER
                mov     hWriter, eax
                invoke  GetDlgItem, hWnd, IDOK
                mov     hStart, eax
               
                invoke  CreateSemaphore, NULL, 1, 1, NULL              ;写线程信号量
                mov     hWSemaphore, eax
                invoke  CreateSemaphore, NULL, 1, 1, NULL              ;控制dwNumber修改的信号量
                mov     hWriterNumber, eax
                invoke  CreateSemaphore, NULL, 1, 1, NULL              ;读线程信号量
                mov     hRSemaphore, eax
                invoke  CreateSemaphore, NULL, 1, 1, NULL              ;控制读线程的信号量
                mov     hRSem, eax
                invoke  CreateSemaphore, NULL, 1, 1, NULL              ;控制dwReader修改的信号量
                mov     hReaderNumber, eax
               
        .else
                mov eax, FALSE
                ret
        .endif
       
        mov eax, TRUE
        ret               
_ProcDlgMain endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
start:
        invoke GetModuleHandle, NULL
        mov    hInstance,eax
        invoke DialogBoxParam, eax, DLG_MAIN,/
               NULL, offset _ProcDlgMain, NULL
        invoke ExitProcess,NULL
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
                end start

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
dsfs
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值