1、用C語言實現--生產者與消費者的問題(PV操作)
這個問題蠻好的
我給你個程序
給我加分啊
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
typedef HANDLE Semaphore; // 信號量的Windows原型
#define P(S) WaitForSingleObject(S, INFINITE) // 定義Windows下的P操作
#define V(S) ReleaseSemaphore(S, 1, NULL) // 定義Windows下的V操作
#define rate 1000
#define CONSUMER_NUM 10 /* 消費者個數 */
#define PRODUCER_NUM 10 /* 生產者個數 */
#define BUFFER_NUM 4 /* 緩沖區個數 */
char *thing[10] = {"豬臉", "牛鞭", "羊腰", "驢蹄", "狼心", "狗肺", "猴肝", "老虎屁股", "大象肚", "河馬大腸"};
struct Buffer
{
int proct[BUFFER_NUM]; // 緩沖區
int start, end; // 兩個指針
} g_buf;
Semaphore g_semBuffer, g_semProct, g_mutex;
// 消費者線程
DWORD WINAPI Consumer(LPVOID para)
{
// i表示第i個消費者
int i = *(int *)para;
int ptr; // 待消費的內容的指針
printf(" 豬頭-%03d: 豬頭我來啦!\n", i);
Sleep(300);
while (1)
{
printf(" 豬頭-%03d: 我要吃.........!\n", i);
// 等待產品
P(g_semProct);
// 有產品,先鎖住緩沖區 g_buf
P(g_mutex);
// 記錄消費的物品
ptr = g_buf.start;
// 再移動緩沖區指針
g_buf.start = (g_buf.start+1)%BUFFER_NUM;
// 讓其他消費者或生產者使用 g_buf
V(g_mutex);
printf(" 豬頭-%03d: 我吃 buf[%d] = %s\n", i, ptr, thing[g_buf.proct[ptr]]);
Sleep(rate*rand()%10+110);
// 消費完畢,並釋放一個緩沖
printf(" 豬頭-%03d: 我爽了! buf[%d] = %s\n", i, ptr, thing[g_buf.proct[ptr]]);
V(g_semBuffer);
}
return 0;
}
// 生產者線程
DWORD WINAPI Procer(LPVOID para)
{
int i = *(int *)para - CONSUMER_NUM;
int ptr;
int data; // 產品
printf("工作狂-%03d: 我來啦!\n", i);
Sleep(300);
while (1)
{
printf("工作狂-%03d: 我乾乾干…………\n", i);
Sleep(rate*rand()%10+110);
data = rand()%10;
printf("工作狂-%03d: 搞出一個東西 data = %s!\n", i, thing[data]);
// 等待存放空間
P(g_semBuffer);
// 有地方,先鎖住緩沖區 g_buf
P(g_mutex);
// 記錄消費的物品
ptr = g_buf.end;
// 再移動緩沖區指針
g_buf.end = (g_buf.end+1)%BUFFER_NUM;
// 讓其他消費者或生產者使用 g_buf
V(g_mutex);
printf("工作狂-%03d: 擱到 buf[%d] = %s\n", i, ptr, thing[data]);
g_buf.proct[ptr] = data;
Sleep(rate/2*rand()%10+110);
// 放好了完畢,釋放一個產品
printf("工作狂-%03d: buf[%d] = %s 放好了,大家吃!\n", i, ptr, thing[g_buf.proct[ptr]]);
V(g_semProct);
}
return 0;
}
int main(int argc, char *argv[])
{
// 線程技術,前面為消費者線程,後面為生產者線程
HANDLE hThread[CONSUMER_NUM+PRODUCER_NUM]; // 線程計數
//srand(time());
DWORD tid;
int i=0;
// 初始化信號量
g_mutex = CreateSemaphore(NULL, BUFFER_NUM, BUFFER_NUM, "mutexOfConsumerAndProcer");
g_semBuffer = CreateSemaphore(NULL, BUFFER_NUM, BUFFER_NUM, "BufferSemaphone");
g_semProct = CreateSemaphore(NULL, 0, BUFFER_NUM, "ProctSemaphone");
if ( !g_semBuffer || !g_semProct || !g_mutex)
{
printf("Create Semaphone Error!\n");
return -1;
}
int totalThreads = CONSUMER_NUM+PRODUCER_NUM;
// 開啟消費者線程
printf("先請豬頭們上席!\n");
for (i=0; i<CONSUMER_NUM; i++)
{
hThread[i] = CreateThread(NULL, 0, Consumer, &i, 0, &tid);
if ( hThread[i] ) WaitForSingleObject(hThread[i], 10);
}
printf("廚子們就位!\n");
for (; i<totalThreads; i++)
{
hThread[i] = CreateThread(NULL, 0, Procer, &i, 0, &tid);
if ( hThread[i] ) WaitForSingleObject(hThread[i], 10);
}
// 生產者和消費者的執行
WaitForMultipleObjects(totalThreads, hThread, TRUE, INFINITE);
return 0;
}
2、c語言實例,linux線程同步的信號量方式 謝謝
這么高的懸賞,實例放後面。信號量(sem),如同進程一樣,線程也可以通過信號量來實現通信,雖然是輕量級的。信號量函數的名字都以"sem_"打頭。線程使用的基本信號量函數有四個。
信號量初始化。3、C語言 static int sem_id = 0:什麼意思
宣告一個靜態變數, 預設為0.
該變數, 可視范圍(可叫用的區塊)不變, 生命周期直到程序結束.
4、急!LINUX下,GCC編譯,原程序包含<semaphore.h>頭文件,為什麼編譯時說sem_wait,sem_post等未定義的引用
編譯時加上參數:-lpthread
要看報錯的階段,是在編譯還是鏈接階段.
如果編譯時函數沒有找到,那是頭文件的問題,如果鏈接時未定義引用,那是c庫的問題.
如果你的頭文件都正常包含了,那可能你的c庫沒有使能semaphore的支持.
5、用C語言實現PV操作生產者消費者關系
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
typedef HANDLE Semaphore; // 信號量的Windows原型
#define P(S) WaitForSingleObject(S, INFINITE) // 定義Windows下的P操作
#define V(S) ReleaseSemaphore(S, 1, NULL) // 定義Windows下的V操作
#define rate 1000
#define CONSUMER_NUM 10 /* 消費者個數 */
#define PRODUCER_NUM 10 /* 生產者個數 */
#define BUFFER_NUM 4 /* 緩沖區個數 */
char *thing[10] = ;
struct Buffer
{
int proct[BUFFER_NUM]; // 緩沖區
int start, end; // 兩個指針
} g_buf;
Semaphore g_semBuffer, g_semProct, g_mutex;
// 消費者線程
DWORD WINAPI Consumer(LPVOID para)
{
// i表示第i個消費者
int i = *(int *)para;
int ptr; // 待消費的內容的指針
printf(" 豬頭-%03d: 豬頭我來啦!\n", i);
Sleep(300);
while (1)
{
printf(" 豬頭-%03d: 我要吃.........!\n", i);
// 等待產品
P(g_semProct);
// 有產品,先鎖住緩沖區 g_buf
P(g_mutex);
// 記錄消費的物品
ptr = g_buf.start;
// 再移動緩沖區指針
g_buf.start = (g_buf.start+1)%BUFFER_NUM;
// 讓其他消費者或生產者使用 g_buf
V(g_mutex);
printf(" 豬頭-%03d: 我吃 buf[%d] = %s\n", i, ptr, thing[g_buf.proct[ptr]]);
Sleep(rate*rand()%10+110);
// 消費完畢,並釋放一個緩沖
printf(" 豬頭-%03d: 我爽了! buf[%d] = %s\n", i, ptr, thing[g_buf.proct[ptr]]);
V(g_semBuffer);
}
return 0;
}
// 生產者線程
DWORD WINAPI Procer(LPVOID para)
{
int i = *(int *)para - CONSUMER_NUM;
int ptr;
int data; // 產品
printf("工作狂-%03d: 我來啦!\n", i);
Sleep(300);
while (1)
{
printf("工作狂-%03d: 我乾乾干…………\n", i);
Sleep(rate*rand()%10+110);
data = rand()%10;
printf("工作狂-%03d: 搞出一個東西 data = %s!\n", i, thing[data]);
// 等待存放空間
P(g_semBuffer);
// 有地方,先鎖住緩沖區 g_buf
P(g_mutex);
// 記錄消費的物品
ptr = g_buf.end;
// 再移動緩沖區指針
g_buf.end = (g_buf.end+1)%BUFFER_NUM;
// 讓其他消費者或生產者使用 g_buf
V(g_mutex);
printf("工作狂-%03d: 擱到 buf[%d] = %s\n", i, ptr, thing[data]);
g_buf.proct[ptr] = data;
Sleep(rate/2*rand()%10+110);
// 放好了完畢,釋放一個產品
printf("工作狂-%03d: buf[%d] = %s 放好了,大家吃!\n", i, ptr, thing[g_buf.proct[ptr]]);
V(g_semProct);
}
return 0;
}
int main(int argc, char *argv[])
{
// 線程技術,前面為消費者線程,後面為生產者線程
HANDLE hThread[CONSUMER_NUM+PRODUCER_NUM]; // 線程計數
//srand(time());
DWORD tid;
int i=0;
// 初始化信號量
g_mutex = CreateSemaphore(NULL, BUFFER_NUM, BUFFER_NUM, "mutexOfConsumerAndProcer");
g_semBuffer = CreateSemaphore(NULL, BUFFER_NUM, BUFFER_NUM, "BufferSemaphone");
g_semProct = CreateSemaphore(NULL, 0, BUFFER_NUM, "ProctSemaphone");
if ( !g_semBuffer || !g_semProct || !g_mutex)
{
printf("Create Semaphone Error!\n");
return -1;
}
int totalThreads = CONSUMER_NUM+PRODUCER_NUM;
// 開啟消費者線程
printf("先請豬頭們上席!\n");
for (i=0; i<CONSUMER_NUM; i++)
{
hThread[i] = CreateThread(NULL, 0, Consumer, &i, 0, &tid);
if ( hThread[i] ) WaitForSingleObject(hThread[i], 10);
}
printf("廚子們就位!\n");
for (; i<totalThreads; i++)
{
hThread[i] = CreateThread(NULL, 0, Procer, &i, 0, &tid);
if ( hThread[i] ) WaitForSingleObject(hThread[i], 10);
}
// 生產者和消費者的執行
WaitForMultipleObjects(totalThreads, hThread, TRUE, INFINITE);
return 0;
}
6、pv 原語實現生產者消費者問題,用C語言編程
下面是我本學期做過的一個課程設計
你可以參考一下,應該差不多
一、如何建立線程
用到的頭文件
(a)pthread.h
(b)semaphore.h
(c) stdio.h
(d)string.h
定義線程標識
pthread_t
創建線程
pthread_create
對應了一個函數作為線程的程序段
注意的問題
要保證進程不結束(在創建線程後加死循環)
在線程中加入While(1)語句,也就是死循環,保證進程不結束。
二、控制線程並發的函數
sem_t:信號量的類型
sem_init:初始化信號量
sem_wait:相當於P操作
sem_post:相當於V操作
三、實現原形系統
父親、母親、兒子和女兒的題目:
桌上有一隻盤子,每次只能放入一隻水果。爸爸專放蘋果,媽媽專放橘子,一個兒子專等吃盤子中的橘子,一個女兒專等吃盤子中的蘋果。分別用P,V操作和管程實現
每個對應一個線程
pthread_t father; father進程
pthread_t mother; mother進程
pthread_t son; son進程
pthread_t daughter; daughter進程
盤子可以用一個變數表示
sem_t empty;
各線程不是只做一次,可以是無限或有限次循環
用While(1)控制各線程無限次循環
輸出每次是那個線程執行的信息
printf("%s\n",(char *)arg);通過參數arg輸出對應線程執行信息
編譯方法
gcc hex.c -lpthread
生成默認的可執行文件a.out
輸入./a.out命令運行
查看結果:程序連續運行顯示出
father input an apple.
daughter get an apple.
mother input an orange.
son get an orange.
mother input an orange.
son get an orange.
………………..
四、程序源代碼
#include <stdio.h>
#include<string.h>
#include <semaphore.h>
#include <pthread.h>
sem_t empty; //定義信號量
sem_t applefull;
sem_t orangefull;
void *procf(void *arg) //father線程
{
while(1){
sem_wait(&empty); //P操作
printf("%s\n",(char *)arg);
sem_post(&applefull); //V操作
sleep(7);
}
}
void *procm(void *arg) //mother線程
{
while(1){
sem_wait(&empty);
printf("%s\n",(char *)arg);
sem_post(&orangefull);
sleep(3);
}
}
void *procs(void *arg) //son線程
{
while(1){
sem_wait(&orangefull);
printf("%s\n",(char *)arg);
sem_post(&empty);
sleep(2);
}
}
void *procd(void *arg) //daughter線程
{
while(1){
sem_wait(&applefull);
printf("%s\n",(char *)arg);
sem_post(&empty);
sleep(5);
}
}
main()
{
pthread_t father; //定義線程
pthread_t mother;
pthread_t son;
pthread_t daughter;
sem_init(&empty, 0, 1); //信號量初始化
sem_init(&applefull, 0, 0);
sem_init(&orangefull, 0, 0);
pthread_create(&father,NULL,procf,"father input an apple."); //創建線程
pthread_create(&mother,NULL,procm,"mother input an orange.");
pthread_create(&daughter,NULL,procd,"daughter get an apple.");
pthread_create(&son,NULL,procs,"son get an orange.");
while(1){} //循環等待
}
7、c語言,做出pv操作
給你提供一個抄思路:參考操作系襲統課程的教材,分別單獨編寫 P、V 操作,設置一個信號量 sem,用於控制可用資源數目。這道題主要考的是操作系統的 P、V 操作的概念問題,C語言只是一個實現該功能的程序而已。
8、linux C編程 信號量sys/sem 有等待超時么
可以用semtimedop
9、c語言指令有哪些啊
你的意思是關鍵字吧。。。
auto :聲明自動變數 一般不使用
double :聲明雙精度變數或函數
int: 聲明整型變數或函數
struct:聲明結構體變數或函數
break:跳出當前循環
else :條件語句否定分支(與 if 連用)
long :聲明長整型變數或函數
switch :用於開關語句
case:開關語句分支
enum :聲明枚舉類型
register:聲明積存器變數
typedef:用以給數據類型取別名(當然還有其他作用)
char :聲明字元型變數或函數
extern:聲明變數是在其他文件正聲明(也可以看做是引用變數)
return :子程序返回語句(可以帶參數,也看不帶參數)
union:聲明聯合數據類型
const :聲明只讀變數
float:聲明浮點型變數或函數
short :聲明短整型變數或函數
unsigned:聲明無符號類型變數或函數
continue:結束當前循環,開始下一輪循環
for:一種循環語句(可意會不可言傳)
signed:生命有符號類型變數或函數
void :聲明函數無返回值或無參數,聲明無類型指針(基本上就這三個作用)
default:開關語句中的「其他」分支
goto:無條件跳轉語句
sizeof:計算數據類型長度
volatile:說明變數在程序執行中可被隱含地改變
do :循環語句的循環體
while :循環語句的循環條件
static :聲明靜態變數
if:條件語句