#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;
}