當前位置:首頁 » 編程語言 » c語言如何實現讀寫者問題
擴展閱讀
webinf下怎麼引入js 2023-08-31 21:54:13
堡壘機怎麼打開web 2023-08-31 21:54:11

c語言如何實現讀寫者問題

發布時間: 2022-05-08 06:18:29

① 用C寫讀者寫者問題

本人也正在做,可以探討,下面是在網上找的
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* ==========宏定義部分========== */
#define FootLoc(p) (p+p->size-1)// 指向p所指結點的底部
#define MINSIZE 10 // 空閑區域最小的底限
#define INITSIZE 500 // 初始化存儲空間的大小
#define Status int // 返回狀態
#define OK 1 // 正確返回值
#define ERROR 0 // 錯誤返回
#define NUM 20 // 內存最大個數
/* ==========結構定義部分========== */
typedef struct WORD // 內存字類型
{
union // head和foot分別是結點的第一個字和最後一個字
{
WORD *link; // 頭部域,指向前趨結點
WORD *uplink; // 底部域,指向本結點頭部
};
int tag; // 塊標志,0:空閑,1:佔用,頭部和尾部均有
int size; // 頭部域,塊大小
WORD *rlink; // 頭部域,指向後繼結點
// char flag[10];
}WORD,head,foot,*Space; // *Space:可利用空間指針類型
typedef struct ProcInf // 分配的進程信息
{
Space Sp_Head; // 進程分配到的內存地址
char name[15]; // 進程描述標識
struct ProcInf *next; // 鏈表指針
}ProcInf;
/* =============函數聲明部分============ */
Space InitMem( int n );
Space AllocBoundTag( WORD *pav, int n );
Status RecycleAlg(Space p,Space pav);
Space DuSort( WORD *pav );
void Insert(WORD *pav,WORD *p);
Space DelNode(ProcInf *h,char id[15]);
Status InsertProInf(ProcInf *h, Space inser, char id[15]);
int main(int argc, char* argv[])
{
WORD *p,*Ret_Proc_Add,*Rec; // p存放申請內存地址的頭指針
ProcInf *pi_h = NULL; // 運行進程鏈表頭指針
int i;
int Num;
int size;
int n = INITSIZE;
char id[15]; // 存放進程標識
pi_h= (ProcInf *)malloc(sizeof(ProcInf)); // 初始化運行進程鏈表頭結點
pi_h ->next =NULL;
p = InitMem(n); // 初始化申請的內存空間,剛開始為一整塊空白內存大小為n
if(!p) // 判斷是否申請成功,失敗結束運行
{
printf("內存初始化失敗!\n");
exit(1);
}
//測試用例
// 輸入要創建進程的個數
printf("要申請的空間個數及其每一個空間所需要的存儲空間:\n");
scanf("%d",&Num);
for( i = 0; i < Num; i++ )
{
L: printf("第%d個空間的存儲空間和空間的ID:",i+1);
scanf("%d%s",&size,id);
getchar(); // 吸收回車符號
Ret_Proc_Add = AllocBoundTag( p, size );// 內存分配大小為size
if(!Ret_Proc_Add) // 判斷內存是否分配成功
{
printf("內存可能不足,分配失敗,重新輸入.\n");
goto L;
}
InsertProInf(pi_h,Ret_Proc_Add,id); // 插入到已經分配的內存鏈表當中
printf("分配內存標識:%s,首地址:0x%x,大小:%d\n",id,Ret_Proc_Add,Ret_Proc_Add ->size);
}
for( i = 0; i < Num; i++ )
{
printf("輸入要回收結點的名字:");
scanf("%s",id);
getchar();
Rec = DelNode(pi_h,id);
if(!Rec)
{
printf("輸入結點無效,請重新輸入.\n");
--i;
}
else
RecycleAlg(Rec,p);
}
getchar();
return 0;
}
Space DelNode(ProcInf *h,char id[15])
{
ProcInf *t,*p;
p = h ->next;
t = h;
if( !p )
{
printf("此空間不存在!\n");
return NULL;
}
while(p ->next!=NULL && strcmp(id,p->name))
{
t = p;
p = p->next;
}
if( p ->next!=NULL )
{
t ->next = p->next;
return p ->Sp_Head;
}
else if(!strcmp(id,p->name))
{
t ->next = p ->next;
return p->Sp_Head;
}
else
{
printf("此空間不存在!\n");
return NULL;
}
}
Status InsertProInf(ProcInf *h,Space inser,char id[15])
{
ProcInf *t,*p;
p = h->next;
if( h->next == NULL )
{
if(!(t = (ProcInf *)malloc(sizeof(ProcInf))))
return ERROR;
t ->Sp_Head = inser;
strcpy( t ->name,id);
t ->next = NULL;
p = t;
h ->next = p;
return OK;
}
else
{
if(!(t = (ProcInf *)malloc(sizeof(ProcInf))))
return ERROR;
t ->Sp_Head = inser;
strcpy( t ->name,id);
t ->next = NULL;
while(p->next)
p = p->next;
p ->next = t;
return OK;
}
}
Space InitMem( int n ) // 初始化分配可利用內存的大小
{
Space p;
p = (Space)malloc(n*sizeof(WORD));
if( p )
{
p ->tag = 0; // 設置使用標志為:未使用
p ->size = n; // 設置大小
p ->rlink = p ->link = p;// 初始化指針
p ->uplink = p; //指向本身
return p;
}
else
return ERROR; // 分配失敗
}
Space AllocBoundTag( WORD *pav, int n ) // 若有不小於n的空閑塊,則分配相應的存
{ // 儲塊,並返回其首地址;否則返回空,若
Space p,f; // 分配後可利用空間表不空,則pav指向表中剛分配過的結點的後繼結點。
// 查找不小於n的空閑塊
for( p = pav; p && p->size < n && p->rlink != pav; p = p->rlink );
if( !p || p->size < n )
return NULL; // 查找失敗返回空指針
else // p指向找到的空閑塊
{
f = FootLoc(p); // f指向此空閑塊的底部
pav = p->rlink; // pav指向*p結點的後繼結點
if( p->size-n <= MINSIZE ) // 整塊分配,不保留<=MINSIZE的剩餘量
{
if( pav == p ) // 如果可利用空間表變為空表,則置pav為空
pav=NULL;
else
{ // 在表中刪除分配的結點
pav->link = p->link;
p->link->rlink=pav;
}
p->tag = f->tag = 1;// 修改分配節點的頭部和底部的標志
}
else // 分配該塊的後n個字
{
f->tag = 1; // 修改分配塊的底部標志
p->size -= n; // 置剩餘塊的大小
f = FootLoc(p); // 指向剩餘塊的底部
f->tag = 0;f->uplink = p;//設置剩餘塊的底部
p = f + 1; // 指向分配塊的頭部
p->tag = 1; // 設置分配塊頭部
p->size = n; // 設置分配塊的大小
}
return p; // 返回分配塊首地址
}
}
Status RecycleAlg(Space p,Space pav) // 回收演算法
{
Space f,q,ql,t,s;
int n;
if( (p-1)->tag != 0 && (p+p->size)->tag != 0 )
{
// 釋放塊的左右鄰區均為佔用塊
printf("釋放塊的左右鄰區均為佔用塊.\n");
p -> tag = 0;
FootLoc(p) ->uplink = p;
FootLoc(p) ->tag = 0;
if( !pav )
pav = p ->link = p ->rlink = p;
else
{
q = pav ->link;
p ->rlink = pav;
p ->link = q;
q ->rlink = pav ->link = p;
pav = p; // 令剛釋放的結點為下次分配時的最先查詢結點
}
}
if((p-1)->tag == 0 && (p+p->size)->tag != 0)
{
// 釋放塊左鄰區為空閑塊
printf("釋放塊左鄰區為空閑塊.\n");
n = p ->size; // 釋放塊的大小
s = (p-1)->uplink; // 左空閑塊的的頭部地址
s ->size += n; // 設置新的空閑塊的大小
f = p + n - 1; // 設置新的空閑塊的底部
f ->uplink = s;
f ->tag = 0;
}
if( (p+p->size)->tag==0 && (p-1)->tag != 0 )
{
//釋放塊的右鄰區為空閑塊
printf("釋放塊的右鄰區為空閑塊.\n");
t = p + p ->size; // 右鄰空閑塊的頭部地址
p ->tag = 0; // p為合並後的結點頭部地址
q =t ->link;
p ->link = q;
q ->rlink = p;
ql = t ->rlink;
p ->rlink = ql;
ql ->link = p;
p ->size += t->size;
FootLoc(t) -> uplink = p;
}
if((p-1)->tag == 0 && (p+p->size)->tag == 0)
{
// 釋放塊的左右鄰塊均為空閑塊
printf("釋放塊的左右鄰塊均為空閑塊.\n");
n = p->size;
s = (p-1)->uplink;
t = p+p->size;
s ->size += n + t ->size;
q = t ->link;
ql = t ->rlink;
q ->rlink = ql;
ql ->link = q;
FootLoc(t) ->uplink = s;
}
return 0;
}
Space DuSort( WORD *pav ) // 雙鏈表排序
{
Space p,q;
p = NULL;
q = pav ->rlink;
if(!pav) return NULL; // 如果為空鏈表,則返回空
while(q -> rlink != q->link) //
{
pav->link->rlink = pav->rlink;
pav->rlink->link = pav->link;
Insert(p,pav);
pav = q;
q = q->rlink;
}
Insert(p,q); // 將最後一個結點插入
return p;
}
void Insert(WORD *pav,WORD *p) // 插入排序,按照可用大小從小到大
{
WORD *t;
t = pav;
if(!pav)
{
pav = p;
pav ->rlink = pav ->link;
}
else
{
while(t->size<p->size)
{
t = t->rlink;
}
p ->rlink =t;
p ->link = t->link;
t ->link->rlink = p;
t ->link = p;
}
}

② 用信號量實現讀寫者同步問題,求詳細程序,VC下可以運行的~

// 最近正好也關注這個問題,下面是我的實現,主要參考自windows 內核實驗教程

#include "windows.h"
#include <conio.h>
#include <stdlib.h>
#include <fstream.h>
#include <io.h>
#include <string.h>
#include <stdio.h>
#include "winbase.h"

#define READER 'R' // 讀者
#define WRITER 'W' // 寫者
#define INTE_PER_SEC 1000 // 每秒時鍾中斷的數目
#define MAX_THREAD_NUM 64 // 最大線程數

int nReaderCnt = 0; // 讀者計數
int nWriterCnt = 0; // 寫者計數

// 使用信號量代替臨界區
HANDLE hWrite = ::CreateSemaphore( NULL, 1, 1, NULL ); // 寫開始信號
HANDLE hRead = ::CreateSemaphore( NULL, 1, 1, NULL ); // 讀開始信號

// 計數器的互斥保護
HANDLE hRCMutex = ::CreateMutex( NULL, FALSE, NULL );
HANDLE hWCMutex = ::CreateMutex( NULL, FALSE, NULL );

// 在寫優先中讀信號
HANDLE hReadMutex = ::CreateMutex( NULL, FALSE, NULL );

// 從測試數據文件中獲取的線程信息
struct ThreadInfo
{
ThreadInfo()
{
nSerialNo = 0;
cType = '^';
dDelayTime = 0.0;
dOpeTime = 0.0;
}
int nSerialNo; // 線程序號
char cType; // 線程類別(判斷是讀者還是寫者線程)
double dDelayTime; // 線程延遲時間
double dOpeTime; // 線程讀寫操作時間
};

///////////////////////////////////////////////////////////////////////////
// 讀者優先---讀者線程
// P:讀者線程信息
void RP_ReaderThread(void *p)
{
// 線程序號
int nSerialNo = ((ThreadInfo*)(p))->nSerialNo ;
DWORD dwReadTime = (DWORD)(((ThreadInfo*)(p))->dOpeTime * INTE_PER_SEC );
DWORD dwDelay = (DWORD)(((ThreadInfo*)(p))->dDelayTime * INTE_PER_SEC );

Sleep( dwDelay );
printf("Reader thread %d sents the reading require.\n",nSerialNo);

// 讀者數目增加
WaitForSingleObject( hRCMutex, INFINITE );
nReaderCnt++;
if( nReaderCnt == 1 )
{
// 第一個讀者, 防寫信號,實現讀寫互斥
WaitForSingleObject( hWrite, INFINITE );
}
ReleaseMutex(hRCMutex);

// 讀文件
printf( "Reader thread %d begins to read file.\n", nSerialNo );
Sleep( dwReadTime );
printf( "Reader thread %d finished reading file.\n", nSerialNo );

// 讀者數目減少
WaitForSingleObject( hRCMutex, INFINITE );
nReaderCnt--;
if( nReaderCnt == 0 )
{
// 如果所有的讀者讀完, 釋放防寫信號
ReleaseSemaphore( hWrite, 1, NULL );
}
ReleaseMutex(hRCMutex);
}

//////////////////////////////////////////////////////////////
// 讀者優先---寫者線程
// P:寫者線程信息
void RP_WriterThread(void *p)
{
// 從參數中獲得信息
int nSerialNo = ((ThreadInfo*)(p))->nSerialNo ;
DWORD dwWriteTime = (DWORD)(((ThreadInfo*)(p))->dOpeTime * INTE_PER_SEC );
DWORD dwDelay = (DWORD)(((ThreadInfo*)(p))->dDelayTime * INTE_PER_SEC );

Sleep( dwDelay );
printf("Write thread %d sents the writing require.\n",nSerialNo);

// 防寫信號
WaitForSingleObject( hWrite, INFINITE );

//寫文件
printf( "Writer thread %d begins to write to the file.\n", nSerialNo );
Sleep( dwWriteTime );
printf( "Write thread %d finished writing to the file.\n", nSerialNo );

ReleaseSemaphore( hWrite, 1, NULL );
}

//////////////////////////////////////////////////////////////
// 讀者優先處理函數
// file:文件名
void ReaderPriority( char *file )
{
//線程數目
int nThreadCnt = 0;
//線程ID
DWORD dwThreadID = 0;

// 初始化讀寫者計數
nReaderCnt = 0;

// 線程對象的數組
HANDLE hThreads[MAX_THREAD_NUM];
ThreadInfo oThreadInfo[MAX_THREAD_NUM];
ifstream inFile;
inFile.open ( file );
printf( "Reader Priority:\n\n" );
while( inFile )
{
// 讀入每一個讀者,寫者的信息
inFile>>oThreadInfo[nThreadCnt].nSerialNo;
inFile>>oThreadInfo[nThreadCnt].cType;
inFile>>oThreadInfo[nThreadCnt].dDelayTime;
inFile>>oThreadInfo[nThreadCnt].dOpeTime;
if ( '^' != oThreadInfo[nThreadCnt].cType )
{
nThreadCnt++;
}
inFile.get();
}

// 創建線程
for( int i = 0; i< nThreadCnt; i++ )
{
if(( oThreadInfo[i].cType==READER ) || ( oThreadInfo[i].cType == 'r' ))
{
// 創建讀者進程
hThreads[i] = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)(RP_ReaderThread),
&oThreadInfo[i], CREATE_SUSPENDED, &dwThreadID );
}
else
{
// 創建寫線程
hThreads[i] = CreateThread( NULL, 0,(LPTHREAD_START_ROUTINE)(RP_WriterThread),
&oThreadInfo[i], CREATE_SUSPENDED, &dwThreadID );
}
}

// 啟動線程
for( i = 0; i< nThreadCnt; i++ )
{
ResumeThread( hThreads[i] );
}

// 等待所有的線程結束
WaitForMultipleObjects( nThreadCnt, hThreads, TRUE, INFINITE );
printf( "All reader and writer have finished operating.\n" );

}

////////////////////////////////////////////////////////
// 寫者優先---讀者線程
// P:讀者線程信息
void WP_ReaderThread( void *p )
{
// 從參數中得到信息
int nSerialNo = ((ThreadInfo*)(p))->nSerialNo ;
DWORD dwReadTime = (DWORD)(((ThreadInfo*)(p))->dOpeTime * INTE_PER_SEC );
DWORD dwDelay = (DWORD)(((ThreadInfo*)(p))->dDelayTime * INTE_PER_SEC );

Sleep( dwDelay );
printf("Reader thread %d sents the reading require.\n",nSerialNo);

// 讀信號互斥保護
WaitForSingleObject( hReadMutex, INFINITE );
// 讀信號
WaitForSingleObject( hRead, INFINITE );
// 增加讀者計數
WaitForSingleObject( hRCMutex, INFINITE );
nReaderCnt++;
if(nReaderCnt==1)
{
// 如果是第1個讀者, 寫信號,以實現讀寫互斥
WaitForSingleObject( hWrite, INFINITE );
}
ReleaseMutex( hRCMutex );
ReleaseSemaphore( hRead, 1, NULL );
ReleaseMutex( hReadMutex );

// 讀文件
printf( "Reader thread %d begins to read file.\n", nSerialNo );
Sleep( dwReadTime );
printf( "Reader thread %d finished reading file.\n", nSerialNo );

// 減少讀者計數
WaitForSingleObject( hRCMutex, INFINITE );
nReaderCnt--;
if( nReaderCnt == 0 )
{
// 最後一個讀者, 喚醒寫者
ReleaseSemaphore( hWrite, 1, NULL );
}
ReleaseMutex( hRCMutex );
}

///////////////////////////////////////////
// 寫者優先---寫者線程
// P:寫者線程信息
void WP_WriterThread( void *p )
{
//從參數中獲得信息
int nSerialNo = ((ThreadInfo*)(p))->nSerialNo;
DWORD dwWriteTime = (DWORD)(((ThreadInfo*)(p))->dOpeTime * INTE_PER_SEC );
DWORD dwDelay = (DWORD)(((ThreadInfo*)(p))->dDelayTime * INTE_PER_SEC );

Sleep( dwDelay );
printf("Writer thread %d sents the writing require.\n",nSerialNo);

// 增加寫者計數
WaitForSingleObject( hWCMutex, INFINITE );
nWriterCnt++;
if( nWriterCnt == 1 )
{
// 為實現寫者優先,獲取讀信號,從而阻塞讀線程
WaitForSingleObject( hRead, INFINITE );
}
ReleaseMutex(hWCMutex);

// 寫信號
WaitForSingleObject( hWrite, INFINITE );
printf( "Writer thread %d begins to write to the file.\n", nSerialNo );
Sleep( dwWriteTime );
printf( "Writer thread %d finished writing to the file.\n", nSerialNo );
ReleaseSemaphore( hWrite, 1, NULL );

// 減少寫者計數
WaitForSingleObject( hWCMutex, INFINITE );
nWriterCnt--;
if( nWriterCnt == 0 )
{
ReleaseSemaphore( hRead, 1, NULL );
}
ReleaseMutex(hWCMutex);
}

/////////////////////////////////////////////
// 寫者優先處理函數
// file:文件名
void WriterPriority( char * file )
{
int nThreadCnt = 0;
DWORD dwThreadID;

HANDLE hThreads[MAX_THREAD_NUM];
ThreadInfo oThreadInfo[MAX_THREAD_NUM];

nReaderCnt=0;
nWriterCnt=0;

ifstream inFile;
inFile.open (file);
printf("Writer priority:\n\n");
while(inFile)
{
inFile>>oThreadInfo[nThreadCnt].nSerialNo;
inFile>>oThreadInfo[nThreadCnt].cType;
inFile>>oThreadInfo[nThreadCnt].dDelayTime;
inFile>>oThreadInfo[nThreadCnt].dOpeTime;
if ( '^' != oThreadInfo[nThreadCnt].cType )
{
nThreadCnt++;
}
inFile.get();
}

// 創建線程
for( int i = 0 ;i < nThreadCnt; i++ )
{
if(( oThreadInfo[i].cType == READER ) || ( oThreadInfo[i].cType == 'r' ))
{
//創建讀者進程
hThreads[i] = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)(WP_ReaderThread),
&oThreadInfo[i], CREATE_SUSPENDED, &dwThreadID );
}
else
{
//創建寫線程
hThreads[i] = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)(WP_WriterThread),
&oThreadInfo[i],CREATE_SUSPENDED,&dwThreadID);
}
}

// 啟動線程
for( i = 0; i< nThreadCnt; i++ )
{
ResumeThread( hThreads[i] );
}

// 等待所有的線程結束
WaitForMultipleObjects( nThreadCnt, hThreads, TRUE, INFINITE );

printf("All reader and writer have finished operating.\n");
}

/////////////////////////////////////////////////////
//主函數
int main(int argc,char *argv[])
{
char ch;
while(true)
{
printf("*************************************\n");
printf(" 1.Reader Priority\n");
printf(" 2.Writer Priority\n");
printf(" 3.Exit to Windows\n");
printf("*************************************\n");
printf("Enter your choice(1,2,3): ");
do{
ch=(char)_getch();
}while(ch!='1'&&ch!='2'&&ch!='3');
system("cls");
if(ch=='3')
return 0;
else if(ch=='1')
ReaderPriority("thread.dat");
else
WriterPriority("thread.dat");
printf("\nPress Any Key to Coutinue:");
_getch();
system("cls");
}
return 0;
}
我可以幫助你,你先設置我最佳答案後,我網路Hii教你。

c語言如何實現對txt文件的讀取和寫入

1、使用VS新建空工程,直接點擊確定,如下所示。

④ 如何用信號量機制解決讀者寫者、生產者消費者問題(C語言)

你到這個連接看看·裡面寫的很詳細的http://wenda.tianya.cn/wenda/thread?tid=225a1aad2c438c22&hl=fi

⑤ C語言中文件的讀寫實際過程

RB和R本質上是二進制數據流,但用於文本的二進制數據的含義是ASCII或其他內部代碼。R/W和Rb/WB之間的一個重要區別是,R/W的文本換行格式在不同的系統上是不同的(DOS/windows下的回車字元Cr('\R')+換行字元LF('\n')、UNIX/Linux下的LF和MAC下的Cr),這導致文件操作的細節不同(例如,通過fput和fprintf處理字元串的結尾)。
具體的讀寫實現由庫函數處理,WB/RB模式一般採用緩沖區讀寫,最終實現對外部內存文件或其他輸入/輸出流的抽象(包括在內存中建立緩沖區)。在此基礎上,w/R模式處理了上述一些差異。通常,緩沖區的操作取決於庫函數的實現。用戶無法看到庫函數,因為它是不必要的(無法保證不同平台的實現是一致的)。
對於標准輸入設備,如鍵盤,它被抽象為標准輸入流stdin。除了抽象過程本身(由底層系統實現)外,實現方法與從外部存儲文件讀取之間沒有本質區別。

⑥ 計算機操作系統中管程機制如何實現讀者寫者

管程實現讀者寫者演算法

管程:bulletin =MODULE ;(假設已實現一基本管程monitor,同時提供了enter,leave,signal,wait等操作)
r,w:condition;
-r 控制讀者使用資源, w 控制寫者使用資源;
writing:boolean;
-當前寫者是否使用資源;
read_account:integer;
define start_read,end_read,start_writer,end_writer;
use monitor.enter,monitor.leave,monitor.wait,monitor.signal;
procere start_read();
{ if (writing) monitor.wait(r);
read_account++;
monitor.signal(r);}
procere end_read();
{read_account--;
if(read_account =0) monitor.signal(w); }
procere start_write();
{ if(read_account<>0) or writing);
monitor.wait(w);
writing=true;
procere end_write();
{ writing=fasle;
if(r<>NULL) monitor.signal(r);
else monitor.signal(w); }
根據上述定義的一系列過程,給出改進後的讀者寫者演算法。
讀者寫者演算法如下:
reader-(讀者進程):
{
while(true)
{
bulletin.enter();
bulletin.start_read();
read();
bulletin.end_read();
bulletin.leave();}
}
writer-(寫者進程):
{
while(ture)
{
bulletin.enter();
bulletin.start_write();
write();
bulletin.end_write();
bulletin.leave();}
}

⑦ 用c語言或c++編寫編程實現生產者消費者或讀寫者的同步問題

實現一個隊列CQueue
CQueue提供兩個公有成員函數
addTail():往隊列尾部增加一個元素
removeHead():讀出並移除隊列的第一個元素
生產者:兩個線程通過調用CQueue::addTail()往隊列中增加元素
消費者:一個線程通過調用CQueue::removeHead()從隊列中讀取元素
#include <iostream>
#include <list>
#include <windows.h>
#include <process.h>
using namespace std;

#define P(sem) WaitForSingleObject(sem,INFINITE)
#define V(sem) ReleaseSemaphore(sem,1,NULL)

class CQueue
{
public:
void addTail();//往隊列尾部增加一個元素
void removeHead();//讀出並移除隊列的第一個元素
private:
list<int> L;
};

CQueue buffer;//全局的緩沖區
const int buf_size = 10;//緩沖區大小

static int GOODS_ID = 0;//商品序號

const int procers = 3;//生產者數量
const int consumers = 8;//消費者數量

void ProcerThread(void* param);
void ConsumerThread(void* param);

HANDLE empty,occupy,op_mutex;

int main()
{
int i;
int p_id[procers],c_id[consumers];
occupy = CreateSemaphore(NULL,0,buf_size,NULL);//佔用位置
empty = CreateSemaphore(NULL,buf_size,buf_size,NULL);//空餘位置
op_mutex = CreateSemaphore(NULL,1,1,NULL);//操作互斥量

for(i=0;i<procers;++i)
{
p_id[i] = i+1;
_beginthread(ProcerThread,0,p_id+i);
}
for(i=0;i<consumers;++i)
{
c_id[i] = i+1;
_beginthread(ConsumerThread,0,c_id+i);
}
while(getchar()=='\n') break;
return 0;
}

void CQueue::addTail()
{
L.insert(L.end(),++GOODS_ID);
}

void CQueue::removeHead()
{
cout<<*L.begin()<<endl;
L.erase(L.begin());
}

void ProcerThread(void* param)
{
int id = *(int*)param;
while(1)
{
P(empty);
P(op_mutex);
Sleep(100);
buffer.addTail();
printf("Procer_%d proced %d\n",id,GOODS_ID);
V(op_mutex);
V(occupy);
}
}

void ConsumerThread(void* param)
{
int id = *(int*)param;
while(1)
{
P(occupy);
P(op_mutex);
Sleep(100);
printf("Consumer_%d consumed ",id);
buffer.removeHead();
V(op_mutex);
V(empty);
}
}

⑧ 讀者-寫者實現

設置互斥信號量wmutex 表示寫者間、讀者和寫者間互斥
用readcount變數來記錄讀者數

Var rmutex,wmutex: semaphore:=1,1 ;
readcount :integer :=0 ;
begin
parbegin

reader:begin
repeat
P(rmutex)
if readcount=0 then P(wmutex);
readcount=readcount+1;
V(rmutex)
read text
P(rmutex)
readcount=readcount+1;
if readcount=0 then V(wmutex);
V(rmutex)
until false

writer:begin
repeat
P(wmutex);
write text;
V(wmutex);
until false
end

parend
end

⑨ c語言如何用信號量實現讀者寫者問題,用wait和signal

網路「最全面的linux信號量解析」。

⑩ 用C語言編程實現用信號量實現讀者--寫者問題(要源代碼)

汗 竟然是校友...
by monkeyking