windows linux 信号量,信号量--操作系统实验总结

#includeint mutexid; //信号量标识 mutexid

int printid; //信号量标识 printid

int readid; //信号量标识 readid

struct sembuf P; //P操作

struct sembuf V; //V操作

union semun arg1; //给信号量赋初值的结构

union semun arg2; //同上

union semun arg3; //同上

FILE *fp; //文件指针

int TotalWords = 0;

int TotalOddWords = 0;

int TotalEvenWords = 0;

void m_print(void *Arg);

void m_read(void *Arg);

int main()

{

mutexid = semget(IPC_PRIVATE,1,0666|IPC_CREAT); //申请只有一个信号量的信号量集

printid = semget(IPC_PRIVATE,1,0666|IPC_CREAT);

readid = semget(IPC_PRIVATE,1,0666|IPC_CREAT);

arg1.val = 1; //赋初值

arg2.val = 0;

arg3.val = 1;

semctl(mutexid,0,SETVAL,arg1); //通过将arg和信号量标识联系起来给信号量赋初值

semctl(printid,0,SETVAL,arg2);

semctl(readid,0,SETVAL,arg3);

P.sem_num = 0;

P.sem_op = -1; //表示为减1操作

P.sem_flg = SEM_UNDO;

V.sem_num = 0;

V.sem_op = 1; //表示为加1操作

V.sem_flg = SEM_UNDO;

pthread_t hReader[3]; //声明线程句柄

pthread_t hPrinter;

if((fp=fopen("/root/abc.c","rt"))==NULL) //尝试打开文件

{

printf("Cannot open file strike any key exit!");

exit(1);

}

int i; //注意:C语言和C++不同,C语言不能在for循环中声明变量int i=0;

int j;

pthread_create(&hPrinter, NULL, (void *)m_print, NULL); //创建线程,注意参数的写法

for(i=0; i<3; i++)

{

pthread_create(&hReader[i], NULL, (void *)m_read, NULL);

}

for(j=0; j<3; j++)

{

pthread_join(hReader[j], NULL); //主线程等待子线程结束

}

pthread_join(hPrinter, NULL);

semctl(mutexid,IPC_RMID,0); //撤销信号量

semctl(readid,IPC_RMID,0);

semctl(printid,IPC_RMID,0);

return 0;

}

void m_print(void *Arg)

{

while(1)

{

semop(printdid,&P,1); //对信号量printid执行P操作

printf("This line includes ");

printf("%d",TotalWords);

printf(" words");

printf("%d",TotalEvenWords);

printf(" even words");

printf("%d",TotalOddWords);

printf(" odd words");

TotalWords = 0;

TotalEvenWords = 0;

TotalOddWords = 0;

semop(readid,&V,1); //对信号量readid执行V操作

}

}

void m_read(void *Arg)

{

while(1)

{

semop(readid,&P,1); //对信号量readid执行P操作

semop(mutexid,&P,1); //对信号量mutexid执行P操作

char ch;

int count = 0;

ch = fgetc(fp); //读取fp所指向的文件内容,放入ch

if(ch == EOF)

{

break;

}

while(ch!='\n')

{

if(ch == ' ')

{

if(count%2 == 0)

{

TotalEvenWords++;

}

else

{

TotalOddWords++;

}

TotalWords++;

count = 0;

}

else

{

count++;

}

putchar(ch); //将ch中的内容输出到屏幕

ch = fgetc(fp);

}

if(count%2 == 0)

{

TotalEvenWords++;

}

else

{

TotalOddWords++;

}

TotalWords++;

putchar('\n');

semop(printid,&V,1); //对信号量printid执行V操作

sleep(1); //等待一段时间

semop(mutexid,&V,1); //对信号量mutexid执行V操作

}

}

Windows下使用信号量,C++实现:

关键API:

1)WaitForSingleObject(p,WaitTime) 相当于 wait(p);

2)ReleaseSemaphore(s,1,NULL); 相当于 signal(s);

3)信号量句柄声明:

HANDLE mutex;

HANDLE p; //打印

HANDLE s; //统计

4)创建信号量:

mutex = CreateSemaphore(NULL,1,1,NULL);

p = CreateSemaphore(NULL,0,1,NULL);

s = CreateSemaphore(NULL,1,1,NULL);

第二个参数为初始值

5)声明线程句柄:

HANDLE thHd;

6)创建线程:

thHd = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)&print,&Printer,0,&Printer.thId);

遇到的问题:

1)文件读写:

判断是否读到末尾用 bool infile.eof()

2)主线程等待子线程:

没有找到API,我只好用了while(1){}永久等待下去了......失败..

源代码:(写的比较罗嗦)

#include#includeusing std::cout;

using std::endl;

using std::ios;

#includeusing std::fstream;

using std::ifstream;

using std::ofstream;

struct Thread

{

HANDLE thHd;

DWORD thId;

int index;

} Reader[3];

Thread Printer;

bool over = false;

HANDLE mutex;

HANDLE p; //打印

HANDLE s; //统计

DWORD WaitTime = 2000;

ifstream infile;

int TotalWords = 0;

int TotalOddWords = 0;

int TotalEvenWords = 0;

void print(Thread printer)

{

while(true)

{

if(WaitForSingleObject(p,WaitTime) == WAIT_OBJECT_0)

{

cout< <

TotalOddWords = 0;

TotalEvenWords = 0;

ReleaseSemaphore(s,1,NULL);

}

}

}

void read(Thread *th)

{

while(!over)

{

if(WaitForSingleObject(s,WaitTime) == WAIT_OBJECT_0)

{

if(WaitForSingleObject(mutex,WaitTime) == WAIT_OBJECT_0)

{

//cout

int count = 0;

infile.get(ch);

if(infile.eof())

{

over = true;

}

else

{

while(ch!='\n')

{

if(ch == ' ')

{

if(count%2 == 0)

{

TotalEvenWords++;

}

else

{

TotalOddWords++;

}

TotalWords++;

count = 0;

}

else

{

count++;

}

cout

if(infile.eof())

{

count--;

break;

}

}

count++;

if(count%2 == 0)

{

TotalEvenWords++;

}

else

{

TotalOddWords++;

}

TotalWords++;

cout< ReleaseSemaphore(p,1,NULL);

ReleaseSemaphore(mutex,1,NULL);

}

}

}

}

}

int main()

{

mutex = CreateSemaphore(NULL,1,1,NULL);

p = CreateSemaphore(NULL,0,1,NULL);

s = CreateSemaphore(NULL,1,1,NULL);

const char *file = "F:\\myFile.txt";

infile.open(file,ios::binary);

if(!infile)

{

cout< return 0;

}

for(int i=0;i<3;i++)

{

Reader[i].index = i;

Reader[i].thHd = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)&read,&Reader[i],0,&Reader[i].thId);

}

Printer.index = 0;

Printer.thHd = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)&print,&Printer,0,&Printer.thId);

//infile.close();

while(1)

{}

return 0;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值