生產(chǎn)者-消費者問題是一個經(jīng)典的進程同步問題,該問題最早由Dijkstra提出,用以演示他提出的信號量機制。在同一個進程地址空間內(nèi)執(zhí)行的兩個線程。生產(chǎn)者線程生產(chǎn)物品,然后將物品放置在一個空緩沖區(qū)中供消費者線程消費。消費者線程從緩沖區(qū)中獲得物品,然后釋放緩沖區(qū)。當(dāng)生產(chǎn)者線程生產(chǎn)物品時,如果沒有空緩沖區(qū)可用,那么生產(chǎn)者線程必須等待消費者線程釋放出一個空緩沖區(qū)。當(dāng)消費者線程消費物品時,如果沒有滿的緩沖區(qū),那么消費者線程將被阻塞,直到新的物品被生產(chǎn)出來。
創(chuàng)新互聯(lián)建站專注于石嘴山企業(yè)網(wǎng)站建設(shè),自適應(yīng)網(wǎng)站建設(shè),電子商務(wù)商城網(wǎng)站建設(shè)。石嘴山網(wǎng)站建設(shè)公司,為石嘴山等地區(qū)提供建站服務(wù)。全流程定制網(wǎng)站,專業(yè)設(shè)計,全程項目跟蹤,創(chuàng)新互聯(lián)建站專業(yè)和態(tài)度為您提供的服務(wù)
#include windows.h
#include iostream
const unsigned short SIZE_OF_BUFFER = 10; //緩沖區(qū)長度
unsigned short ProductID = 0; //產(chǎn)品號
unsigned short ConsumeID = 0; //將被消耗的產(chǎn)品號
unsigned short in = 0; //產(chǎn)品進緩沖區(qū)時的緩沖區(qū)下標
unsigned short out = 0; //產(chǎn)品出緩沖區(qū)時的緩沖區(qū)下標
int g_buffer[SIZE_OF_BUFFER]; //緩沖區(qū)是個循環(huán)隊列
bool g_continue = true; //控制程序結(jié)束
HANDLE g_hMutex; //用于線程間的互斥
HANDLE g_hFullSemaphore; //當(dāng)緩沖區(qū)滿時迫使生產(chǎn)者等待
HANDLE g_hEmptySemaphore; //當(dāng)緩沖區(qū)空時迫使消費者等待
DWORD WINAPI Producer(LPVOID); //生產(chǎn)者線程
DWORD WINAPI Consumer(LPVOID); //消費者線程
int main()
{
//創(chuàng)建各個互斥信號
g_hMutex = CreateMutex(NULL,FALSE,NULL);
g_hFullSemaphore = CreateSemaphore(NULL,SIZE_OF_BUFFER-1,SIZE_OF_BUFFER-1,NULL);
g_hEmptySemaphore = CreateSemaphore(NULL,0,SIZE_OF_BUFFER-1,NULL);
//調(diào)整下面的數(shù)值,可以發(fā)現(xiàn),當(dāng)生產(chǎn)者個數(shù)多于消費者個數(shù)時,
//生產(chǎn)速度快,生產(chǎn)者經(jīng)常等待消費者;反之,消費者經(jīng)常等待
const unsigned short PRODUCERS_COUNT = 3; //生產(chǎn)者的個數(shù)
const unsigned short CONSUMERS_COUNT = 1; //消費者的個數(shù)
//總的線程數(shù)
const unsigned short THREADS_COUNT = PRODUCERS_COUNT+CONSUMERS_COUNT;
HANDLE hThreads[PRODUCERS_COUNT]; //各線程的handle
DWORD producerID[CONSUMERS_COUNT]; //生產(chǎn)者線程的標識符
DWORD consumerID[THREADS_COUNT]; //消費者線程的標識符
//創(chuàng)建生產(chǎn)者線程
for (int i=0;iPRODUCERS_COUNT;++i){
hThreads[i]=CreateThread(NULL,0,Producer,NULL,0,producerID[i]);
if (hThreads[i]==NULL) return -1;
}
//創(chuàng)建消費者線程
for (int i=0;iCONSUMERS_COUNT;++i){
hThreads[PRODUCERS_COUNT+i]=CreateThread(NULL,0,Consumer,NULL,0,consumerID[i]);
if (hThreads[i]==NULL) return -1;
}
while(g_continue){
if(getchar()){ //按回車后終止程序運行
g_continue = false;
}
}
return 0;
}
//生產(chǎn)一個產(chǎn)品。簡單模擬了一下,僅輸出新產(chǎn)品的ID號
void Produce()
{
std::cerr "Producing " ++ProductID " ... ";
std::cerr "Succeed" std::endl;
}
//把新生產(chǎn)的產(chǎn)品放入緩沖區(qū)
void Append()
{
std::cerr "Appending a product ... ";
g_buffer[in] = ProductID;
in = (in+1)%SIZE_OF_BUFFER;
std::cerr "Succeed" std::endl;
//輸出緩沖區(qū)當(dāng)前的狀態(tài)
for (int i=0;iSIZE_OF_BUFFER;++i){
std::cout i ": " g_buffer[i];
if (i==in) std::cout " -- 生產(chǎn)";
if (i==out) std::cout " -- 消費";
std::cout std::endl;
}
}
//從緩沖區(qū)中取出一個產(chǎn)品
void Take()
{
std::cerr "Taking a product ... ";
ConsumeID = g_buffer[out];
out = (out+1)%SIZE_OF_BUFFER;
std::cerr "Succeed" std::endl;
//輸出緩沖區(qū)當(dāng)前的狀態(tài)
for (int i=0;iSIZE_OF_BUFFER;++i){
std::cout i ": " g_buffer[i];
if (i==in) std::cout " -- 生產(chǎn)";
if (i==out) std::cout " -- 消費";
std::cout std::endl;
}
}
//消耗一個產(chǎn)品
void Consume()
{
std::cerr "Consuming " ConsumeID " ... ";
std::cerr "Succeed" std::endl;
}
//生產(chǎn)者
DWORD WINAPI Producer(LPVOID lpPara)
{
while(g_continue){
WaitForSingleObject(g_hFullSemaphore,INFINITE);
WaitForSingleObject(g_hMutex,INFINITE);
Produce();
Append();
Sleep(1500);
ReleaseMutex(g_hMutex);
ReleaseSemaphore(g_hEmptySemaphore,1,NULL);
}
return 0;
}
//消費者
DWORD WINAPI Consumer(LPVOID lpPara)
{
while(g_continue){
WaitForSingleObject(g_hEmptySemaphore,INFINITE);
WaitForSingleObject(g_hMutex,INFINITE);
Take();
Consume();
Sleep(1500);
ReleaseMutex(g_hMutex);
ReleaseSemaphore(g_hFullSemaphore,1,NULL);
}
return 0;
是什么樣的程序我不清楚。
不過你可以定義一個 bool變量當(dāng)開關(guān)嘛, 比如p操作時為 true,v操作時為false, 這樣就可以分開兩個操作了
一個是Posix實現(xiàn),一個是System V實現(xiàn)
使用的環(huán)境不一樣
一般來講SV的適用于進程同步,POSIX適用于線程同步
System V進程同步 api:semget/semop/semctl
POSIX 線程同步 api:sem_init/sem_destroy
不過POSIX貌似還會分為有名和無名信號量上面說的是無名信號量。
具體的還要看使用的環(huán)境。
這么高的懸賞,實例放后面。信號量(sem),如同進程一樣,線程也可以通過信號量來實現(xiàn)通信,雖然是輕量級的。信號量函數(shù)的名字都以"sem_"打頭。線程使用的基本信號量函數(shù)有四個。
信號量初始化。
int?sem_init?(sem_t?*sem?,?int?pshared,?unsigned?int?value);
這是對由sem指定的信號量進行初始化,設(shè)置好它的共享選項(linux?只支持為0,即表示它是當(dāng)前進程的局部信號量),然后給它一個初始值VALUE。
等待信號量。給信號量減1,然后等待直到信號量的值大于0。
int?sem_wait(sem_t?*sem);
釋放信號量。信號量值加1。并通知其他等待線程。
int?sem_post(sem_t?*sem);
銷毀信號量。我們用完信號量后都它進行清理。歸還占有的一切資源。
int?sem_destroy(sem_t?*sem);
#include?stdlib.h??
#include?stdio.h??
#include?unistd.h??
#include?pthread.h??
#include?semaphore.h??
#include?errno.h??
#define?return_if_fail(p)?if((p)?==?0){printf?("[%s]:func?error!/n",?__func__);return;}??
typedef?struct?_PrivInfo??
{??
sem_t?s1;??
sem_t?s2;??
time_t?end_time;??
}PrivInfo;??
static?void?info_init?(PrivInfo*?thiz);??
static?void?info_destroy?(PrivInfo*?thiz);??
static?void*?pthread_func_1?(PrivInfo*?thiz);??
static?void*?pthread_func_2?(PrivInfo*?thiz);??
int?main?(int?argc,?char**?argv)??
{??
pthread_t?pt_1?=?0;??
pthread_t?pt_2?=?0;??
int?ret?=?0;??
PrivInfo*?thiz?=?NULL;??
thiz?=?(PrivInfo*?)malloc?(sizeof?(PrivInfo));??
if?(thiz?==?NULL)??
{??
printf?("[%s]:?Failed?to?malloc?priv./n");??
return?-1;??
}??
info_init?(thiz);??
ret?=?pthread_create?(pt_1,?NULL,?(void*)pthread_func_1,?thiz);??
if?(ret?!=?0)??
{??
perror?("pthread_1_create:");??
}??
ret?=?pthread_create?(pt_2,?NULL,?(void*)pthread_func_2,?thiz);??
if?(ret?!=?0)??
{??
perror?("pthread_2_create:");??
}??
pthread_join?(pt_1,?NULL);??
pthread_join?(pt_2,?NULL);??
info_destroy?(thiz);??
return?0;??
}??
static?void?info_init?(PrivInfo*?thiz)??
{??
return_if_fail?(thiz?!=?NULL);??
thiz-end_time?=?time(NULL)?+?10;??
sem_init?(thiz-s1,?0,?1);??
sem_init?(thiz-s2,?0,?0);??
return;??
}??
static?void?info_destroy?(PrivInfo*?thiz)??
{??
return_if_fail?(thiz?!=?NULL);??
sem_destroy?(thiz-s1);??
sem_destroy?(thiz-s2);??
free?(thiz);??
thiz?=?NULL;??
return;??
}??
static?void*?pthread_func_1?(PrivInfo*?thiz)??
{??
return_if_fail(thiz?!=?NULL);??
while?(time(NULL)??thiz-end_time)??
{??
sem_wait?(thiz-s2);??
printf?("pthread1:?pthread1?get?the?lock./n");??
sem_post?(thiz-s1);??
printf?("pthread1:?pthread1?unlock/n");??
sleep?(1);??
}??
return;??
}??
static?void*?pthread_func_2?(PrivInfo*?thiz)??
{??
return_if_fail?(thiz?!=?NULL);??
while?(time?(NULL)??thiz-end_time)??
{??
sem_wait?(thiz-s1);??
printf?("pthread2:?pthread2?get?the?unlock./n");??
sem_post?(thiz-s2);??
printf?("pthread2:?pthread2?unlock./n");??
sleep?(1);??
}??
return;??
}
實現(xiàn)一個隊列CQueue
CQueue提供兩個公有成員函數(shù)
addTail():往隊列尾部增加一個元素
removeHead():讀出并移除隊列的第一個元素
生產(chǎn)者:兩個線程通過調(diào)用CQueue::addTail()往隊列中增加元素
消費者:一個線程通過調(diào)用CQueue::removeHead()從隊列中讀取元素
#include iostream
#include list
#include windows.h
#include process.h
using namespace std;
#define P(sem) WaitForSingleObject(sem,INFINITE)
#define V(sem) ReleaseSemaphore(sem,1,NULL)
class CQueue
{
public:
void addTail();//往隊列尾部增加一個元素
void removeHead();//讀出并移除隊列的第一個元素
private:
listint L;
};
CQueue buffer;//全局的緩沖區(qū)
const int buf_size = 10;//緩沖區(qū)大小
static int GOODS_ID = 0;//商品序號
const int producers = 3;//生產(chǎn)者數(shù)量
const int consumers = 8;//消費者數(shù)量
void ProducerThread(void* param);
void ConsumerThread(void* param);
HANDLE empty,occupy,op_mutex;
int main()
{
int i;
int p_id[producers],c_id[consumers];
occupy = CreateSemaphore(NULL,0,buf_size,NULL);//占用位置
empty = CreateSemaphore(NULL,buf_size,buf_size,NULL);//空余位置
op_mutex = CreateSemaphore(NULL,1,1,NULL);//操作互斥量
for(i=0;iproducers;++i)
{
p_id[i] = i+1;
_beginthread(ProducerThread,0,p_id+i);
}
for(i=0;iconsumers;++i)
{
c_id[i] = i+1;
_beginthread(ConsumerThread,0,c_id+i);
}
while(getchar()=='\n') break;
return 0;
}
void CQueue::addTail()
{
L.insert(L.end(),++GOODS_ID);
}
void CQueue::removeHead()
{
cout*L.begin()endl;
L.erase(L.begin());
}
void ProducerThread(void* param)
{
int id = *(int*)param;
while(1)
{
P(empty);
P(op_mutex);
Sleep(100);
buffer.addTail();
printf("Producer_%d produced %d\n",id,GOODS_ID);
V(op_mutex);
V(occupy);
}
}
void ConsumerThread(void* param)
{
int id = *(int*)param;
while(1)
{
P(occupy);
P(op_mutex);
Sleep(100);
printf("Consumer_%d consumed ",id);
buffer.removeHead();
V(op_mutex);
V(empty);
}
}
linux中的進程通信分為三個部分:低級通信,管道通信和進程間通信IPC(inter process communication)。linux的低級通信主要用來傳遞進程的控制信號——文件鎖和軟中斷信號機制。linux的進程間通信IPC有三個部分——①信號量,②共享內(nèi)存和③消息隊列。以下是我編寫的linux進程通信的C語言實現(xiàn)代碼。操作系統(tǒng)為redhat9.0,編輯器為vi,編譯器采用gcc。下面所有實現(xiàn)代碼均已經(jīng)通過測試,運行無誤。
一.低級通信--信號通信
signal.c
#include
#include
#include
/*捕捉到信號sig之后,執(zhí)行預(yù)先預(yù)定的動作函數(shù)*/
void sig_alarm(int sig)
{
printf("---the signal received is %d. /n", sig);
signal(SIGINT, SIG_DFL); //SIGINT終端中斷信號,SIG_DFL:恢復(fù)默認行為,SIN_IGN:忽略信號
}
int main()
{
signal(SIGINT, sig_alarm);//捕捉終端中斷信號
while(1)
{
printf("waiting here!/n");
sleep(1);
}
return 0;
}
二.管道通信
pipe.c
#include
#define BUFFER_SIZE 30
int main()
{
int x;
int fd[2];
char buf[BUFFER_SIZE];
char s[BUFFER_SIZE];
pipe(fd);//創(chuàng)建管道
while((x=fork())==-1);//創(chuàng)建管道失敗時,進入循環(huán)
/*進入子進程,子進程向管道中寫入一個字符串*/
if(x==0)
{
sprintf(buf,"This is an example of pipe!/n");
write(fd[1],buf,BUFFER_SIZE);
exit(0);
}
/*進入父進程,父進程從管道的另一端讀出剛才寫入的字符串*/
else
{
wait(0);//等待子進程結(jié)束
read(fd[0],s,BUFFER_SIZE);//讀出字符串,并將其儲存在char s[]中
printf("%s",s);//打印字符串
}
return 0;
}
三.進程間通信——IPC
①信號量通信
sem.c
#include
#include
#include
#include types.h
#include ipc.h
#include sem.h
/*聯(lián)合體變量*/
union semun
{
int val; //信號量初始值
struct semid_ds *buf;
unsigned short int *array;
struct seminfo *__buf;
};
/*函數(shù)聲明,信號量定義*/
static int set_semvalue(void); //設(shè)置信號量
static void del_semvalue(void);//刪除信號量
static int semaphore_p(void); //執(zhí)行P操作
static int semaphore_v(void); //執(zhí)行V操作
static int sem_id; //信號量標識符
int main(int argc, char *argv[])
{
int i;
int pause_time;
char op_char = 'O';
srand((unsigned int)getpid());
sem_id = semget((key_t)1234, 1, 0666 | IPC_CREAT);//創(chuàng)建一個信號量,IPC_CREAT表示創(chuàng)建一個新的信號量
/*如果有參數(shù),設(shè)置信號量,修改字符*/
if (argc 1)
{
if (!set_semvalue())
{
fprintf(stderr, "Failed to initialize semaphore/n");
exit(EXIT_FAILURE);
}
op_char = 'X';
sleep(5);
}
for(i = 0; i 10; i++)
{
/*執(zhí)行P操作*/
if (!semaphore_p())
exit(EXIT_FAILURE);
printf("%c", op_char);
fflush(stdout);
pause_time = rand() % 3;
sleep(pause_time);
printf("%c", op_char);
fflush(stdout);
/*執(zhí)行V操作*/
if (!semaphore_v())
exit(EXIT_FAILURE);
pause_time = rand() % 2;
sleep(pause_time);
}
printf("/n%d - finished/n", getpid());
if (argc 1)
{
sleep(10);
del_semvalue(); //刪除信號量
}
exit(EXIT_SUCCESS);
}
/*設(shè)置信號量*/
static int set_semvalue(void)
{
union semun sem_union;
sem_union.val = 1;
if (semctl(sem_id, 0, SETVAL, sem_union) == -1)
return(0);
return(1);
}
/*刪除信號量*/
static void del_semvalue(void)
{
union semun sem_union;
if (semctl(sem_id, 0, IPC_RMID, sem_union) == -1)
fprintf(stderr, "Failed to delete semaphore/n");
}
/*執(zhí)行P操作*/
static int semaphore_p(void)
{
struct sembuf sem_b;
sem_b.sem_num = 0;
sem_b.sem_op = -1; /* P() */
sem_b.sem_flg = SEM_UNDO;
if (semop(sem_id, sem_b, 1) == -1)
{
fprintf(stderr, "semaphore_p failed/n");
return(0);
}
return(1);
}
/*執(zhí)行V操作*/
static int semaphore_v(void)
{
struct sembuf sem_b;
sem_b.sem_num = 0;
sem_b.sem_op = 1; /* V() */
sem_b.sem_flg = SEM_UNDO;
if (semop(sem_id, sem_b, 1) == -1)
{
fprintf(stderr, "semaphore_v failed/n");
return(0);
}
return(1);
}
②消息隊列通信
send.c
#include
#include
#include
#include
#include
#include types.h
#include ipc.h
#include msg.h
#define MAX_TEXT 512
/*用于消息收發(fā)的結(jié)構(gòu)體--my_msg_type:消息類型,some_text:消息正文*/
struct my_msg_st
{
long int my_msg_type;
char some_text[MAX_TEXT];
};
int main()
{
int running = 1;//程序運行標識符
struct my_msg_st some_data;
int msgid;//消息隊列標識符
char buffer[BUFSIZ];
/*創(chuàng)建與接受者相同的消息隊列*/
msgid = msgget((key_t)1234, 0666 | IPC_CREAT);
if (msgid == -1)
{
fprintf(stderr, "msgget failed with error: %d/n", errno);
exit(EXIT_FAILURE);
}
/*向消息隊列中發(fā)送消息*/
while(running)
{
printf("Enter some text: ");
fgets(buffer, BUFSIZ, stdin);
some_data.my_msg_type = 1;
strcpy(some_data.some_text, buffer);
if (msgsnd(msgid, (void *)some_data, MAX_TEXT, 0) == -1)
{
fprintf(stderr, "msgsnd failed/n");
exit(EXIT_FAILURE);
}
if (strncmp(buffer, "end", 3) == 0)
{
running = 0;
}
}
exit(EXIT_SUCCESS);
}
receive.c
#include
#include
#include
#include
#include
#include types.h
#include ipc.h
#include msg.h
/*用于消息收發(fā)的結(jié)構(gòu)體--my_msg_type:消息類型,some_text:消息正文*/
struct my_msg_st
{
long int my_msg_type;
char some_text[BUFSIZ];
};
int main()
{
int running = 1;//程序運行標識符
int msgid; //消息隊列標識符
struct my_msg_st some_data;
long int msg_to_receive = 0;//接收消息的類型--0表示msgid隊列上的第一個消息
/*創(chuàng)建消息隊列*/
msgid = msgget((key_t)1234, 0666 | IPC_CREAT);
if (msgid == -1)
{
fprintf(stderr, "msgget failed with error: %d/n", errno);
exit(EXIT_FAILURE);
}
/*接收消息*/
while(running)
{
if (msgrcv(msgid, (void *)some_data, BUFSIZ,msg_to_receive, 0) == -1)
{
fprintf(stderr, "msgrcv failed with error: %d/n", errno);
exit(EXIT_FAILURE);
}
printf("You wrote: %s", some_data.some_text);
if (strncmp(some_data.some_text, "end", 3) == 0)
{
running = 0;
}
}
/*刪除消息隊列*/
if (msgctl(msgid, IPC_RMID, 0) == -1)
{
fprintf(stderr, "msgctl(IPC_RMID) failed/n");
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
}
③共享內(nèi)存通信
share.h
#define TEXT_SZ 2048 //申請共享內(nèi)存大小
struct shared_use_st
{
int written_by_you; //written_by_you為1時表示有數(shù)據(jù)寫入,為0時表示數(shù)據(jù)已經(jīng)被消費者提走
char some_text[TEXT_SZ];
};
producer.c
#include
#include
#include
#include
#include types.h
#include ipc.h
#include shm.h
#include "share.h"
int main()
{
int running = 1; //程序運行標志位
void *shared_memory = (void *)0;
struct shared_use_st *shared_stuff;
char buffer[BUFSIZ];
int shmid; //共享內(nèi)存標識符
/*創(chuàng)建共享內(nèi)存*/
shmid = shmget((key_t)1234, sizeof(struct shared_use_st), 0666 | IPC_CREAT);
if (shmid == -1)
{
fprintf(stderr, "shmget failed/n");
exit(EXIT_FAILURE);
}
/*將共享內(nèi)存連接到一個進程的地址空間中*/
shared_memory = shmat(shmid, (void *)0, 0);//指向共享內(nèi)存第一個字節(jié)的指針
if (shared_memory == (void *)-1)
{
fprintf(stderr, "shmat failed/n");
exit(EXIT_FAILURE);
}
printf("Memory attached at %X/n", (int)shared_memory);
shared_stuff = (struct shared_use_st *)shared_memory;
/*生產(chǎn)者寫入數(shù)據(jù)*/
while(running)
{
while(shared_stuff-written_by_you == 1)
{
sleep(1);
printf("waiting for client.../n");
}
printf("Enter some text: ");
fgets(buffer, BUFSIZ, stdin);
strncpy(shared_stuff-some_text, buffer, TEXT_SZ);
shared_stuff-written_by_you = 1;
if (strncmp(buffer, "end", 3) == 0)
{
running = 0;
}
}
/*該函數(shù)用來將共享內(nèi)存從當(dāng)前進程中分離,僅使得當(dāng)前進程不再能使用該共享內(nèi)存*/
if (shmdt(shared_memory) == -1)
{
fprintf(stderr, "shmdt failed/n");
exit(EXIT_FAILURE);
}
printf("producer exit./n");
exit(EXIT_SUCCESS);
}
customer.c
#include
#include
#include
#include
#include types.h
#include ipc.h
#include shm.h
#include "share.h"
int main()
{
int running = 1;//程序運行標志位
void *shared_memory = (void *)0;
struct shared_use_st *shared_stuff;
int shmid; //共享內(nèi)存標識符
srand((unsigned int)getpid());
/*創(chuàng)建共享內(nèi)存*/
shmid = shmget((key_t)1234, sizeof(struct shared_use_st), 0666 | IPC_CREAT);
if (shmid == -1)
{
fprintf(stderr, "shmget failed/n");
exit(EXIT_FAILURE);
}
/*將共享內(nèi)存連接到一個進程的地址空間中*/
shared_memory = shmat(shmid, (void *)0, 0);//指向共享內(nèi)存第一個字節(jié)的指針
if (shared_memory == (void *)-1)
{
fprintf(stderr, "shmat failed/n");
exit(EXIT_FAILURE);
}
printf("Memory attached at %X/n", (int)shared_memory);
shared_stuff = (struct shared_use_st *)shared_memory;
shared_stuff-written_by_you = 0;
/*消費者讀取數(shù)據(jù)*/
while(running)
{
if (shared_stuff-written_by_you)
{
printf("You wrote: %s", shared_stuff-some_text);
sleep( rand() % 4 );
shared_stuff-written_by_you = 0;
if (strncmp(shared_stuff-some_text, "end", 3) == 0)
{
running = 0;
}
}
}
/*該函數(shù)用來將共享內(nèi)存從當(dāng)前進程中分離,僅使得當(dāng)前進程不再能使用該共享內(nèi)存*/
if (shmdt(shared_memory) == -1)
{
fprintf(stderr, "shmdt failed/n");
exit(EXIT_FAILURE);
}
/*將共享內(nèi)存刪除,所有進程均不能再訪問該共享內(nèi)存*/
if (shmctl(shmid, IPC_RMID, 0) == -1)
{
fprintf(stderr, "shmctl(IPC_RMID) failed/n");
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
}
摘自:
分享標題:信號量函數(shù)用c語言怎么寫 C語言信號
瀏覽路徑:http://aaarwkj.com/article10/docpggo.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供移動網(wǎng)站建設(shè)、動態(tài)網(wǎng)站、品牌網(wǎng)站建設(shè)、品牌網(wǎng)站制作、App設(shè)計、企業(yè)建站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)