5.多线程:生产者/消费者 linux 下

wyqiang 2006-06-14 10:37:29
/*
5.多线程:生产者/消费者

有两个线程,生产线程负责产生随机自然数(>0),每次产生一个,产生好后放入一个数组构成的缓冲区。消费线程负责取出来,显示在屏幕上。缓冲区的number字段为0时表示为该缓冲区为空闲;否则为忙状态。


当缓冲区都处于忙状态时,生产线程要等待缓冲区中有空闲缓冲区,即等待消费线程进行消费;当缓冲区都处于空闲状态时,消费线程要等待生产线程生产。


实现者必须体会这句话的含义,即条件变量。
缓冲区的记录定义如下:

struct node_st {

int number;

struct node_st *next;

};

typedef struct node_st node_st;

node_st pool[10]; /* 缓冲区个数为10个 */

 

要求:

1) 消费线程每取走一个自然数,则将该缓冲区置成0, 即将 node_st 的 number 字段置成0

2) 生成线程检验缓冲区是否为空的依据是判断node_st 的 number 字段是否为0

3) 不容许生产线程和消费线程同时访问缓冲区

4) 使用 mutex, semaphore 等 线程同步对象,通信对象

5) 不能使用 Sleep 等函数来同步线程,但可以使用Sleep来调节生产或消费的速度。

6) 使用VC的 console 工程,将生产线程产生的自然数和消费线程消费的自然数输出在屏幕上。
*/
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>

struct node_st
{
int number;
struct node_st * next;
};
typedef struct node_st node_st;

node_st * head;

pthread_mutext_t mutex=PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond=PTHREAD_COND_INITIALIZER;

node_st * initalizing()
{
node_st * r;
node_st * pointer ;
int i;

head=r=(node_st *)malloc(sizeof(node_st));
head->number=0;


for(i=1; i<=10; i++)
{
pointer=(node_st *)malloc(sizeof(node_st));
pointer->number=0;
r->next=pointer;
r=pointer;
}
r->next=NULL;
return head;
}

void print(node_st * head)
{
node_st * tmp;

tmp = head;
while(tmp->next!=NULL)
{
printf("%d \r\n",tmp->number);
tmp=tmp->next;
}
}

void * pro(void *)
{
int i=0;

node_st * tmp;

while(1)
{
tmp = head;

int num=rand ()*10;
while(num ==0)
num=rand ()*10;

pthread_mutex_lock(&mutex);

while(tmp->number>0)
{
if(tmp->next==NULL)
tmp = tmp->next;
i++;
}

if(i == 0)
pthread_cond_broadcast(&cond);
if(i == 10)
pthread_cond_wait(&cond,&mutex);
tmp->number=num;
printf("Product %d\r\n",tmp->number);

pthread_mutex_unlock(&mutex);
}
}

void *con(void *)
{
node_st * tmp;
node_st * r;
int i = 0;
while(1)
{
tmp = head;

pthread_mutex_lock(&mutex);

while((tmp->number > 0)&&(tmp->next!=NULL))
{
r=tmp;
tmp = tmp->next;
}

if(i == 10)
pthread_cond_broadcast(&cond);
if(i == 0)
pthread_cond_wait(&cond,&mutex);

printf("Consume %d\r\n",r->number);
r->number=0;

pthread_mutex_unlock(&mutex);
}

}

/*
void deleteall(node_st * head)
{
node_st * tmp =head;
while(tmp->next!=NULL)
{
head=tmp->next;
delete tmp;
tmp=head;
}
delete head;
}
*/


int main(int argc,char **args)
{
pthread_t product;
pthread_t consume;
head=initalizing();

pthread_create(&product,NULL,pro,NULL);
pthread_create(&consume,NULL,con,NULL);
pthread_join(product,NULL);
pthread_join(consume,NULL);

return 0;
}


...全文
553 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
healer_kx 2006-06-15
  • 打赏
  • 举报
回复
up
zhousqy 2006-06-15
  • 打赏
  • 举报
回复
while(tmp->number>0)
{
if(tmp->next==NULL)
tmp = tmp->next;
i++;
}
------------------
这段代码是不是有问题啊!
jixingzhong 2006-06-15
  • 打赏
  • 举报
回复
楼主你在作这么 ?

问题?
程序不是都在了么?
avalonBBS 2006-06-15
  • 打赏
  • 举报
回复

永远爱接分^___^
sonald 2006-06-15
  • 打赏
  • 举报
回复
永远爱老师~~
du51 2006-06-15
  • 打赏
  • 举报
回复
这应该是一系列的问题.原来我做过.
楼主也真老实.凑够100分问一题...
你不会申请几个号呀..呵呵..
开玩笑的.
wyqiang 2006-06-14
  • 打赏
  • 举报
回复
/*
* 2.排序

* 假如已有如下字符串数组,
* char *ppszStrings[] = {"wave", "car", "for", "extern", "abc", "do", "123"};
* 请使用冒泡排序法按照升序排序后,仍然放置到ppszStrings中。
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream.h>

int main(int argc,char **agrs)
{
char *ppszStrings[] = {"wave", "car", "for", "extern", "abc"};
int count = sizeof(ppszStrings)/sizeof(char *);
char *temp;

for(int i=0; i<count; i++)
{
for(int j=i+1; j<count; j++)
{
if(strcmp(ppszStrings[i], ppszStrings[j])<0)
{
temp = ppszStrings[i];
ppszStrings[i] = ppszStrings[j];
ppszStrings[j] = temp;

}
}
}

for(int k=0; k<count; k++)
printf("%s\r\n", ppszStrings[k]);


return 0;
}
wyqiang 2006-06-14
  • 打赏
  • 举报
回复
/*
3.字符串指针(*)

CanonicalFileName实现正规化文件名称
规整规则为:
将名称中的 "and" 字符串替换为 "&"字符串
将名称中的".."字符串上退一层;
将名称中的"."字符去掉;
将名称中的"\\"变成"\";
例如:文件名为 "c:\\test\..\test\.\and" 规整为 "c:\test\&"


/* @[in]
* pszFile 需要正规化的文件名
* @[out]
* 返回值0标示成功,非0标示失败
* pszCanoFile 正规化过的文件名, 实现者必须为pszCanoFile分配内存。
*

int CanonicalFileName(const char *pszFile, char **pszCanoFile)
{
...
}

void main(int argc, char **argv)
{
CanonicalFileName(...);
}

*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int CanonicalFileName(const char *pszFile, char **pszCanoFile)
{
char path[256];
char * p , * q;
strcpy(path,pszFile);


while(p = strstr(path,"..\\"))
{
q = p-1;
while(*q == '\\')q--;
while(*q != '\\')q--;
*q = 0;
strcat(path,p+2);
}

while(p = strstr(path,".\\"))
{
*p=0;
strcat(path,p+2);
}


while(p = strstr(path,"and"))
{
*p=0;
strcat(path,"&");
strcat(path,p+3);
}


*pszCanoFile=0;
*pszCanoFile=(char*)malloc(sizeof(char)*strlen(path+1));
if(pszCanoFile)
strcpy(*pszCanoFile,path);
return 0;
}

int main(int argc,char **agrs)
{
const char *pszFile="c:\\\\test\\..\\test\\.\\and";
char *pszCanoFile;
CanonicalFileName(pszFile,&pszCanoFile);
puts(pszCanoFile);
return 0;
}
wyqiang 2006-06-14
  • 打赏
  • 举报
回复
/*4.指针数组

实现一个函数将字符串";abc;def;ghi;jk;"以';'分割为字符串数组。并返回输出,实现下列:

@[in]
* pszString 表示传入字符串";abc;def;ghi;jk;"
* @[out]
* pszArray 表示分割后组成的字符串数组;
* pnCount 标示分割后字符串的个数。

int Split(const char *pszString, char ***pszArray, long *pnCount)
{
...
}

int main(int argc, char **argv)
{
...
}

*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_STRING_SIZE (100)

int CountSubString(char* pszString, long* pnCount, int* pnMaxSize)
{
long nCount = 0;
int ii;
int nMax = 0;
char* pcStr = pszString;

while(*pcStr != '\0')
{
if(*pcStr == ';')
{
if(nMax < ii)
nMax = ii;

nCount++;
ii = 0;
}
else
{
ii++;
}

if((*pcStr != ';') && (*(pcStr+sizeof(char)) == '\0'))
nCount++;

pcStr++;
}

if(nCount > 0)
{
*pnCount = nCount;
*pnMaxSize = nMax;
}

return 0;
}

int Split(char* pszString, char*** pppszArray, long* pnCount)
{
int nMax = 0;
int ii;
int jj;
char* pcStr = pszString;

CountSubString(pszString, pnCount, &nMax);
if(*pnCount <= 0)
{
printf("\nsub string is 0!\n");
return -1;
}

*pppszArray = (char**)malloc(sizeof(long)*(*pnCount));
for(ii = 0; ii < *pnCount; ii++)
{
(*pppszArray)[ii] = (char*)malloc(sizeof(char)*nMax);
}

ii = 0;
jj = 0;

while(*pcStr != '\0')
{
if(*pcStr != ';')
{
(*pppszArray)[ii][jj] = *pcStr;
jj++;
}
else
{
(*pppszArray)[ii][jj] = '\0';
jj = 0;
ii++;
}

pcStr++;
}

return 0;
}


int main(int argc, char **argv)
{
char** ppStr;
long nCount = 0;
int ii;
char szInputStr[MAX_STRING_SIZE];

printf("please input a string:\n");
scanf("%s", szInputStr);

Split(szInputStr, &ppStr, &nCount);
for(ii = 0; ii < nCount; ii++)
printf("%s\n", ppStr[ii]);

return 0;
}

69,373

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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