线程安全型双向链表的实现

紫藤罗 2013-11-22 11:31:59
求助:
运行如下程序
// ConsoleApplication14.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include<stdlib.h>
#include<stdio.h>
#include<windows.h>
#include<process.h>
#include<dos.h>
#include <conio.h>
#include<fstream>
using namespace std;

HANDLE h_Mutex; //定义互斥量(用于线程1互斥)
HANDLE hSemaphore; //定义信号量(用于线程2和线程3互斥)
char szName[]="shmtu.semaphore"; //定义信号量名称(可以不写)

struct Node{ //定义链表节点(结构体)
int ID; //定义节点ID
struct Node *next; //定义指向下一节点指针
struct Node *prior; //定义指向上一节点指针
};

struct ThreadInfo{ //定义进程结构体(用于线程1)
int ID; //定义线程ID
int internumber; //定义线程加入节点的数量
int delay; //定义线程开始时间
int persist; //定义线程持续时间
};

struct Node *head=NULL,*tail=NULL; //定义链表头指针和尾指针,初始值为空
int number=0; //定义节点数量,初始值为0


void print(Node *node){ //打印链表函数
struct Node *p1; //定义一个指针
p1=node; //指针指向print(*node)读入的指针node
if(p1!=NULL){ //如果指针不为空则打印链表
do{ //正向打印链表
printf("%d ",p1->ID);
p1=p1->next;
}while(p1!=node);
printf("\n");
do{ //反向打印链表(正反向都打印说明我们建立的是双向循环链表)
printf("%d ",p1->ID);
p1=p1->prior;
}while(p1!=node);
printf("\n");
}
}
struct Node *creat(){ //建立链表函数
struct Node *newNode; //定义一个指针
printf("\n---------------------------------\n");
printf("请输入你想建立的链表长度:");
scanf_s("%d",&number); //获得建立链表的长度
for(int i=0;i<number;i++){ //为节点开辟内存空间
newNode=(struct Node *)malloc(sizeof(struct Node));
if(i==0) //i=0时说明是第一个节点
{
head=newNode; //将之前定义的head指针指向第一个节点
newNode->ID=i;
head->next=head;
head->prior=head;
tail=head;
}
else{ //i!=0说明不是第一个节点,则添加在后面.
newNode->ID=tail->ID+1;
tail->next=newNode;
newNode->prior=tail;
tail=newNode;
tail->next=head;
head->prior=tail;
}
}
printf("建立的链表为:\n");
print(head);
printf("---------------------------------\n");
return tail;
}

struct Node *Insert(Node *node,int number2){ //添加节点函数
struct Node *newNode;
for(int i=0;i<number2;i++){
newNode=(struct Node *)malloc(sizeof(struct Node));
newNode->ID=tail->ID+1;
tail->next=newNode;
newNode->prior=tail;
tail=newNode;
tail->next=head;
head->prior=tail;
}
return tail;
}

void count(){
struct Node *p1;
p1=head;
while(p1->next!=head){
number++;
p1=p1->next;
};
printf("%d\n",number+1);
}


unsigned __stdcall threadTest1(void *pA) //线程1
{
DWORD m_delay; //延迟时间
DWORD m_persist; //读文件持续时间
DWORD m_number=0; //插入的节点个数
int m_serial; //线程序号
m_serial = ((ThreadInfo *)(pA))->ID;
m_number = (DWORD)(((ThreadInfo*)(pA))->internumber);
m_delay = (DWORD)(((ThreadInfo *)(pA))->delay*1000);
m_persist = (DWORD)(((ThreadInfo*)(pA))->persist*1000);
Sleep (m_delay) ; //延迟等待
printf("\n");
printf("线程%d准备修改链表......\n",m_serial);
WaitForSingleObject(h_Mutex,INFINITE); //信号量初始值为0,所以线程阻塞,等待信号量的值大于0
Insert(tail,m_number);
printf("线程%d正在插入%d个节点....\n",m_serial,m_number);
Sleep(m_persist);
printf("线程%d修改完成,结果为:",m_serial);
print(head);
ReleaseMutex(h_Mutex);
return 0;
}
unsigned __stdcall threadTest2(void *pA) //线程2
{
int *a=(int *)pA;
WaitForSingleObject(hSemaphore,INFINITE); //信号量初始值为0,所以线程阻塞,等待信号量的值大于0
Insert(tail,100000);
printf("\n线程%d正在向链表中插入100000个节点\n",a);
ReleaseSemaphore(hSemaphore, 1, NULL); //signal(S)的操作释放信号量,进行解锁
printf("线程%d已插入完毕\n",a);
count();
return 0;
}

unsigned __stdcall threadTest3(void *pA) //线程3
{
int *a=(int *)pA;
WaitForSingleObject(hSemaphore,INFINITE); //信号量初始值为0,所以线程阻塞,等待信号量的值大于0
Insert(tail,100000);
printf("\n线程%d正在向链表中插入100000个节点\n",a);
ReleaseSemaphore(hSemaphore, 1, NULL); //signal(S)的操作释放信号量,进行解锁
printf("线程%d已插入完毕\n",a);
return 0;
}
int exam_process(){

DWORD n_thread = 0; // 线程数目
UINT thread_ID; // 线程ID
DWORD wait_for_all; // 等待所有线程结束
h_Mutex = CreateMutex(NULL,FALSE,"mutex_for_thread");
HANDLE Thread[10];
ThreadInfo thread_info[10];
ifstream inFile; // 打开文件
inFile.open("zp.txt");
while(inFile)
{
//读人每一个读者、写者的信息
inFile>>thread_info[n_thread].ID;
inFile>>thread_info[n_thread].internumber;
inFile>>thread_info[n_thread].delay;
inFile>>thread_info[n_thread++].persist;
inFile.get();
}
for(int i=0;i<(int)(n_thread);i++){
Thread[i]=(HANDLE)_beginthreadex(NULL,0,threadTest1, &thread_info[i],0,NULL);
}
wait_for_all = WaitForMultipleObjects(n_thread,Thread,TRUE,-1) ;
printf("\n所有进程已完成修改,修改结果如下所示:\n");
print(head);
//关闭线程句柄,关闭信号量句柄
for(int i = 0; i < (int)(n_thread); i++)
{
CloseHandle(Thread[i]);
}
CloseHandle(h_Mutex);
return 0;
}

int exam_number()
{
HANDLE hThread[2];
hSemaphore = CreateSemaphore(NULL, 1, 1, NULL); //创建一个信号量,初始值0,明初始值为1,最大值也为1,相当于互斥量mutex
hThread[0]=(HANDLE)_beginthreadex(NULL,0,threadTest2,(void*)1,0,NULL);
hThread[1]=(HANDLE)_beginthreadex(NULL,0,threadTest3,(void*)2,0,NULL);
WaitForSingleObject(hThread[0],-1);
WaitForSingleObject(hThread[1],-1);
count();
CloseHandle(hThread[0]);
CloseHandle(hThread[1]);
CloseHandle(hSemaphore);
return 0;
}


int main(){
char ch;
system("cls");
while ( true )
{
printf("***********************************\n");
printf(" 1: 建立链表 \n") ;
printf(" 2: 线程序列检验\n") ;
printf(" 3: 结点个数统计检验\n") ;
printf(" 4: 退出\n") ;
printf("***********************************\n");
printf( "Enter your choice (1 ~ 4):\n ");
do{ //如果输入信息不正确,继续输入
ch = (char)_getch() ;
}while(ch != '1' && ch != '2'&& ch != '3'&& ch != '4');
if(ch == '4') { printf( "\n");return 0; } // 选择4,退出
if(ch == '3') exam_number(); // 选择3
if(ch == '2') exam_process(); // 选择2
if(ch == '1') *creat(); // 选择1
_getch() ;
system("cls") ;
}
//结束
printf("\nPress Any Key To Continue:");
_getch() ;
return 0;
}

运行时出现如下错误:
d:\ruanjian\c\113\114.cpp(55) : error C2065: 'scanf_s' : undeclared identifier
d:\ruanjian\c\113\114.cpp(170) : error C2065: '_beginthreadex' : undeclared identifier
d:\ruanjian\c\113\114.cpp(176) : error C2374: 'i' : redefinition; multiple initialization
d:\ruanjian\c\113\114.cpp(169) : see declaration of 'i'
执行 cl.exe 时出错
请问这个怎么解决啊?
谢谢~
...全文
629 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
EdYan 2013-11-26
  • 打赏
  • 举报
回复
引用 7 楼 u012615829 的回复:
恩 已经弄好了 谢谢啊
同学你是海事大学的?
SKATE11 2013-11-22
  • 打赏
  • 举报
回复
d:\ruanjian\c\113\114.cpp(55) : error C2065: 'scanf_s' : undeclared identifier 直接用scanf吧 d:\ruanjian\c\113\114.cpp(170) : error C2065: '_beginthreadex' : undeclared identifier 包含相应头文件 d:\ruanjian\c\113\114.cpp(176) : error C2374: 'i' : redefinition; multiple initialization 变量i重复定义了 看看是不是定义了两个i d:\ruanjian\c\113\114.cpp(169) : see declaration of 'i'
紫藤罗 2013-11-22
  • 打赏
  • 举报
回复
恩 已经弄好了 谢谢啊
赵4老师 2013-11-22
  • 打赏
  • 举报
回复
引用 4 楼 u012615829 的回复:
大哥 刚刚我把工程改成多线程之后又出现了新的问题cannot open file "mfcapwzd.lib" 这个怎么弄啊??
重建新项目,类型选Win32 Console
赵4老师 2013-11-22
  • 打赏
  • 举报
回复
'scanf_s' : undeclared identifier 换高版本的VC
紫藤罗 2013-11-22
  • 打赏
  • 举报
回复
大哥 刚刚我把工程改成多线程之后又出现了新的问题cannot open file "mfcapwzd.lib" 这个怎么弄啊??
紫藤罗 2013-11-22
  • 打赏
  • 举报
回复
我想问一下 d:\ruanjian\c\113\114.cpp(170) : error C2065: '_beginthreadex' : undeclared identifier 包含相应头文件 这个怎么改呀?
紫藤罗 2013-11-22
  • 打赏
  • 举报
回复
好的 我看看 谢谢哈

64,649

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧