我知道这可能是一个重复的问题,但我还没有找到解决问题的方法。
我试图用C语言写一个成长型社会的模拟,其中有两种类型的人,A和B(在我的例子中有2个人)。
A
,B
和gestore
之间的通信gestore
决定每个人的属性"然后使用execve
创建它们,将每个属性作为参数传递我在Linux Mint 18.3 32位下。
它始终在文件
中提供错误堆栈粉碎检测#ifndef _HEAD_H
#define _HEAD_H
#include <unistd.h>
#include <sys/msg.h>
#define OFFSET 1000000
union semun {
int val;
struct semid_ds *buf;
unsigned short *array;
struct seminfo *__buf;
};
struct person{
char type;
int name;
unsigned long genome;
};
struct msg_text {
pid_t pid;
char type;
int name;
unsigned long genome;
int key_of_love;
pid_t partner;
};
struct mymsg {
long mtype;
struct msg_text mtxt;
};
int initSemAvailable(int, int);
int initSemInUse(int, int);
int reserveSem(int, int);
int releaseSem(int, int);
#endif
#include <sys/sem.h>
#include <sys/types.h>
#include "header.h"
int initSemAvailable(int semId, int semNum)
{
union semun arg;
arg.val = 1;
return semctl(semId, semNum, SETVAL, arg);
}
int initSemInUse(int semId, int semNum)
{
union semun arg;
arg.val = 0;
return semctl(semId, semNum, SETVAL, arg);
}
int reserveSem(int semId, int semNum) {
struct sembuf sops;
sops.sem_num = semNum;
sops.sem_op = -1;
sops.sem_flg = 0;
return semop(semId, &sops, 1);
}
int releaseSem(int semId, int semNum) {
struct sembuf sops;
sops.sem_num = semNum;
sops.sem_op = 1;
sops.sem_flg = 0;
return semop(semId, &sops, 1);
}
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
#include <time.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include "header.h"
#ifndef MAX_PEOPLE
#define MAX_PEOPLE 5
#endif
#ifndef GENES
#define GENES 1000000
#endif
#ifndef BIRTH_DEATH
#define BIRTH_DEATH 5
#endif
#define SIZE_N 15
//handle signals
struct sigaction sa;
sigset_t my_mask;
void handle_signal(int);
//remove every IPC object
void remove_all();
//terminate every child
void terminate_children();
//free memory
void free_all();
//print every field of message
void print_msg(struct mymsg);
unsigned int init_people;
int * child_status;
pid_t * initial_children;
char * child_name;
char * child_genome;
char * child_sem;
char * child_sem2;
char * child_msgq_a;
//message queue
struct msqid_ds msq;
int msgq_a;
//semaphores
int sem_init_people;
int sem_init_people2;
int main(void)
{
init_people = 0;//will contain initial number of people
int i = 0;
pid_t child;//fork value
unsigned long random_ulong = 0;
child_name = (char *)calloc(SIZE_N, sizeof(char));
child_genome = (char *)calloc(SIZE_N, sizeof(char));
child_sem = (char*)calloc(SIZE_N, sizeof(char));
child_sem2 = (char*)calloc(SIZE_N, sizeof(char));
child_msgq_a = (char*)calloc(SIZE_N, sizeof(char));
char * args[8] = {};
char * envs[] = {NULL};
if( child_name == NULL || child_genome == NULL
|| child_sem == NULL || child_sem2 == NULL
|| child_msgq_a == NULL){
perror("there's a null variable");
exit(EXIT_FAILURE);
}
//handle signals
sa.sa_handler = &handle_signal;
sa.sa_flags = 0;
sigemptyset(&my_mask);
sigaction(SIGALRM, &sa, NULL);
sigaction(SIGUSR1, &sa, NULL);
printf("\nSTARTING SIMULATION\n\n");
init_people = 2;
initial_children = (pid_t *)calloc(init_people,
sizeof(pid_t));
//create 2 semaphores
sem_init_people = semget(IPC_PRIVATE, 1,
0666|IPC_CREAT|IPC_EXCL);
if( sem_init_people == -1 ){
if(errno == EEXIST){
if( semctl(sem_init_people, 0,
IPC_RMID, NULL) == -1 ){
perror("rm sem_init_people");
exit(EXIT_FAILURE);
}
}else{
perror("semget init_people");
exit(EXIT_FAILURE);
}
}
sem_init_people2 = semget(IPC_PRIVATE, 1,
0666|IPC_CREAT|IPC_EXCL);
if( sem_init_people2 == -1 ){
if(errno == EEXIST){
if( semctl(sem_init_people2, 0,
IPC_RMID, NULL) == -1 ){
perror("remove sem_init_people2");
exit(EXIT_FAILURE);
}
}else{
perror("semget sem_init_people2");
exit(EXIT_FAILURE);
}
}
//create message queue
msgq_a = msgget(IPC_PRIVATE, 0666|IPC_CREAT|IPC_EXCL);
if(msgq_a == -1){
if( errno == EEXIST ){//if exists
// delete message queue
if( msgctl(msgq_a, IPC_RMID, &msq) == -1 )
perror("rmid");
}else
perror("msgget queue A");
exit(EXIT_FAILURE);
}
//initialize sem_init_people to 0 (reserved)
if( initSemInUse(sem_init_people, 0) == -1 ){
perror("initSemInUse for sem_init_people");
exit(EXIT_FAILURE);
}
//initialize sem_init_people2 to 0 (reserved)
if( initSemInUse(sem_init_people2, 0) == -1 ){
perror("initSemInUse for sem_init_people");
exit(EXIT_FAILURE);
}
//RWX permissions for people processes
if( chmod("./A", 0777) != 0 ){
perror("chmod person A");
exit(EXIT_FAILURE);
}
if( chmod("./B", 0777) != 0 ){
perror("chmod person B");
exit(EXIT_FAILURE);
}
printf("Generating %u people\n\n", init_people);
//generate initial population
for(i = 0; i < init_people; i++){
//TYPE
if( i%2 == 0 )
args[0] = "./A";
else
args[0] = "./B";
//NAME
if( sprintf(child_name, "%d", i+65) < 0 ){
perror("printf NAME execve");
exit(EXIT_FAILURE);
}
args[1] = child_name;
//GENOME
if( sprintf(child_genome, "%lu",
(long)i+100000) < 0 ){
perror("sprintf GENOME execve");
exit(EXIT_FAILURE);
}
args[2] = child_genome;
//semaphore 1
if( sprintf(child_sem, "%d",
sem_init_people) < 0 ){
perror("sprintf sem_init_prople execve");
exit(EXIT_FAILURE);
}
args[3] = child_sem;
//semaphore 2
if( sprintf(child_sem2, "%d",
sem_init_people2) < 0 ){
perror("sprintf sem_init_prople2 execve");
exit(EXIT_FAILURE);
}
args[4] = child_sem2;
//msg queue
if( sprintf(child_msgq_a, "%d", msgq_a) < 0 ){
perror("sprintf child_msgq_a execve");
exit(EXIT_FAILURE);
}
args[5] = child_msgq_a;
//final argument
args[6] = NULL;
switch(child = fork()){
case -1:{ //error
perror("fork init_people");
exit(EXIT_FAILURE);
}
case 0:{//child
if( execve(args[0], args, envs) == -1 ){
perror("execve");
}
//execve didnt't work
exit(EXIT_FAILURE);
}
default:{//parent
printf("[type:%c][name:%c][pid:%d][gen:%s][sem1:%s]\
[sem2:%s][msgq:%s]\n",
args[0][2],
atoi(args[1]),
(int)child,
args[2],
args[3],
args[4],
args[5] );
//add every child in the array
initial_children[i] = child;
}
}//-switch
}//-for
//wait for every child to be ready to start
for(i = 0; i < init_people; i++){
if( reserveSem(sem_init_people, 0) != 0 ){
perror("reserveSem sem_init_people");
exit(EXIT_FAILURE);
}
}
//allow every child to start
for(i = 0; i < init_people; i++){
if( releaseSem(sem_init_people2, 0) != 0 ){
perror("releaseSem sem_init_people2");
exit(EXIT_FAILURE);
}
}
//wait for termination of every child
if( waitpid(-1, child_status, (int)WNOHANG) == -1 ){
perror("waitpid");
}
printf("Father is now waiting...\n");
for(i = 0; i < 3; i++){
sleep(3);
}
terminate_children();
remove_all();
free_all();
return EXIT_SUCCESS;
}
void handle_signal(int signum)
{
switch(signum){
case SIGUSR1:{
pid_t pidA = 0, pidB = 0;
unsigned long genomeA = 0, genomeB = 0;
struct mymsg msg1, msg2;
int msg_flag = 0;
//ignore sigusr1
if( sigaddset(&my_mask, SIGUSR1) == -1 ){
perror("sigaddset");
exit(EXIT_FAILURE);
}
//read for every message
while(msg_flag == 0){
if( msgrcv(msgq_a, &msg1, sizeof(msg1),
OFFSET+getpid(), IPC_NOWAIT) == -1 ){
if( errno == ENOMSG ){
msg_flag = -1;
printf("gestore is empty\n");
}else{ //random error happened
perror("msgrcv parent A and B");
exit(EXIT_FAILURE);
}
}else{
print_msg(msg1);
msg_flag = 0;
}
}
//do not ignore SIGUSR1
if( sigdelset(&my_mask, SIGUSR1) == -1 ){
perror("sigdelset");
exit(EXIT_FAILURE);
}
break;
}
default:{}
}
}
void terminate_children()
{
int i = 0;
for(i = 0; i < init_people; i++){
if( kill(initial_children[i], 0) == 0 ){
if( kill(initial_children[i], SIGTERM) == -1){
perror("kill sigterm to child");
}
}
}
}
void remove_all()
{
//...
}
void free_all()
{
//...
}
void print_msg(struct mymsg msg)
{
printf("gestore rcv [mtype:%lu][pid:%d][type:%c]\
[name:%c][gen:%lu][key<3:%d][pid<3:%d]\n",
msg.mtype,
(int)msg.mtxt.pid,
msg.mtxt.type,
msg.mtxt.name,
msg.mtxt.genome,
msg.mtxt.key_of_love,
(int)msg.mtxt.partner );
}
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <errno.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/types.h>
#include <sys/wait.h>
#include "header.h"
#define NMEMB 50
void accept_lover(int msgq, int love_msg_queue,
struct mymsg love_letter, struct person myself);
void reject_lover(int, struct mymsg love_letter);
struct sigaction sa;
void handle_signal(int);
void print_rcvd_msg(struct mymsg);
void print_sent_msg(struct mymsg);
struct msqid_ds msq;
int love_msg_queue;
int main(int argc, char** argv)
{
if(argc < 6){
perror("A argc");
exit(EXIT_FAILURE);
}
struct person myself;//info of A process
myself.type = 'A';
myself.name = (int)atoi(argv[1]);
myself.genome = (unsigned long)atol(argv[2]);
int sem_init_people, sem_init_people2;
sem_init_people = (int)atoi(argv[3]);
sem_init_people2 = (int)atoi(argv[4]);
int msgq = atoi(argv[5]);
struct mymsg msg_out, love_letter;
struct msqid_ds msq;
int engaged = -1;
int count_refused = 0;
sa.sa_handler = &handle_signal;
sigaction(SIGTERM, &sa, NULL);
//tell parent you're ready
if( releaseSem(sem_init_people, 0) != 0 ){
perror("releaseSem sem_init_people");
exit(EXIT_FAILURE);
}
//wait for parent permission
if( reserveSem(sem_init_people2, 0) != 0 ){
perror("reserveSem sem_init_people2");
exit(EXIT_FAILURE);
}
//create personal message queue of love
love_msg_queue = msgget(IPC_PRIVATE,
0666|IPC_CREAT|IPC_EXCL);
if( love_msg_queue == -1 ){
if( errno == EEXIST ){//if exists
// delete message queue
if( msgctl(love_msg_queue,
IPC_RMID, &msq) == -1 ){
perror("rmid queue of love");
exit(EXIT_FAILURE);
}
}else{
perror("msgget queue of love");
exit(EXIT_FAILURE);
}
}
//create message with correct info of process A
msg_out.mtype = myself.genome;
msg_out.mtxt.pid = getpid();
msg_out.mtxt.type = myself.type;
msg_out.mtxt.genome = myself.genome;
msg_out.mtxt.name = myself.name;
msg_out.mtxt.key_of_love = love_msg_queue;
msg_out.mtxt.partner = -1;
//when A accepts B engaged = 0
while(engaged != 0){
//send info in message queue
if( msgsnd(msgq, &msg_out, sizeof(msg_out), 0)
== -1 ){
if(errno == EINTR)
perror("A caught a signal and failed \
a blocked msgsnd");
else
perror("A msgsnd");
exit(EXIT_FAILURE);
}
print_sent_msg(msg_out);
//wait for love letter from B
if( msgrcv(love_msg_queue, &love_letter,
sizeof(love_letter), 0, 0) == -1 ){
perror("A msgrcv love letter from B");
exit(EXIT_FAILURE);
}
print_rcvd_msg(love_letter);
//accept B if..
if( count_refused >= 2 ){
engaged = 0;//B is good, EXIT loop
accept_lover(msgq, love_msg_queue,
love_letter, myself);
printf("[A:%d]accepted[B:%d]\n",(int)getpid(),
(int)love_letter.mtxt.pid);
}else{
reject_lover(love_msg_queue,love_letter);
printf("[A:%d] refused %d times\n",
(int)getpid(),count_refused+1);
count_refused++;
}
}
pause();
return EXIT_SUCCESS;
}
void handle_signal(int signum)
{
switch(signum){
case SIGTERM:{
printf("A SIGTERM from parent\n");
// delete message queue if exists
if( (msgctl(love_msg_queue, IPC_RMID,
&msq) == -1) && (errno != EIDRM) ){
perror("A rmid 2");
}
break;
}
default:{}
}
}
void accept_lover(int msgq, int love_msg_queue,
struct mymsg love_letter, struct person myself)
{
struct mymsg
msg_to_B, msg_to_gestore1, msg_to_gestore2;
//tell B you accept his request (key_of_love = 0)
msg_to_B.mtype = love_letter.mtype; //pid of B
msg_to_B.mtxt.pid = getpid();
msg_to_B.mtxt.type = 'A';
msg_to_B.mtxt.name = myself.name;
msg_to_B.mtxt.genome = myself.genome;
msg_to_B.mtxt.key_of_love = 0; //0 means accepted
msg_to_B.mtxt.partner = -1;
//send msg to B in queue of love
if( msgsnd(love_msg_queue, &msg_to_B,
sizeof(msg_to_B), 0) == -1 ){
perror("A msgsnd to B accept lover");
exit(EXIT_FAILURE);
}
print_sent_msg(msg_to_B);
//tell gestore that A accepted a request from B
//send message with info of A
//send message with info of B
//A
msg_to_gestore1.mtype = OFFSET + getppid();
msg_to_gestore1.mtxt.pid = getpid();
msg_to_gestore1.mtxt.type = 'A';
msg_to_gestore1.mtxt.name = myself.name;
msg_to_gestore1.mtxt.genome = myself.genome;
msg_to_gestore1.mtxt.key_of_love = 0;
msg_to_gestore1.mtxt.partner = love_letter.mtype;
//B
msg_to_gestore2.mtype = OFFSET + getppid();
msg_to_gestore2.mtxt.pid = love_letter.mtype;
msg_to_gestore2.mtxt.type = 'B';
msg_to_gestore2.mtxt.name = love_letter.mtxt.name;
msg_to_gestore2.mtxt.genome = love_letter.mtxt.genome;
msg_to_gestore2.mtxt.key_of_love = 0;
msg_to_gestore2.mtxt.partner = getpid();
//send msg B
if( msgsnd(msgq, &msg_to_gestore2,
sizeof(msg_to_gestore2), 0) == -1 ){
perror("A msg_to_gestore2");
exit(EXIT_FAILURE);
}
//send msg A
if( msgsnd(msgq, &msg_to_gestore1,
sizeof(msg_to_gestore1), 0) == -1 ){
perror("A msg_to_gestore1");
exit(EXIT_FAILURE);
}
print_sent_msg(msg_to_gestore2);
print_sent_msg(msg_to_gestore1);
/*messages for gestore have mtype=OFFSET+father_pid
so that others can't read messages with mtype greater
than OFFSET and father can directly receive messages
knowing both OFFSET and his pid. */
}
void reject_lover(int love_msg_queue,
struct mymsg love_letter)
{
love_letter.mtxt.key_of_love = -1;
if( (msgsnd(love_msg_queue, &love_letter,
sizeof(love_letter), 0) == -1) ){
perror("A error refusing B in msgsnd");
exit(EXIT_FAILURE);
}
print_sent_msg(love_letter);
}
void print_rcvd_msg(struct mymsg msg)
{
printf("A received [mtype:%lu][pid:%d][type:%c]\
[name:%c][gen:%lu][key<3:%d][pid<3:%d]\n",
msg.mtype,
(int)msg.mtxt.pid,
msg.mtxt.type,
msg.mtxt.name,
msg.mtxt.genome,
msg.mtxt.key_of_love,
(int)msg.mtxt.partner );
}
void print_sent_msg(struct mymsg msg)
{
printf("A sent [mtype:%lu][pid:%d][type:%c][name:%c]\
[gen:%lu][key<3:%d][pid<3:%d]\n",
msg.mtype,
(int)msg.mtxt.pid,
msg.mtxt.type,
msg.mtxt.name,
msg.mtxt.genome,
msg.mtxt.key_of_love,
(int)msg.mtxt.partner );
}
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include "header.h"
//send message to A process and wait for response
int flirt(struct mymsg msg, struct person myself);
void print_rcvd_msg(struct mymsg);
void print_sent_msg(struct mymsg);
int main(int argc, char** argv)
{
if(argc < 6){
perror("B argc");
exit(EXIT_FAILURE);
}
struct person myself;
myself.type = 'B';
myself.name = (int)atoi(argv[1]);
myself.genome = (unsigned long)atol(argv[2]);
int sem_init_people, sem_init_people2;
sem_init_people = (int)atoi(argv[3]);
sem_init_people2 = (int)atoi(argv[4]);
int love_response = 1;
int msgq = atoi(argv[5]);
struct mymsg msg_out, msg_in;
struct msqid_ds msq;
//tell parent you're ready
if( releaseSem(sem_init_people, 0) != 0 ){
perror("release sem_init_people child proc");
exit(EXIT_FAILURE);
}
//wait for parent permission to start living
if( reserveSem(sem_init_people2, 0) != 0 ){
perror("reserve sem_init_people2 child proc");
exit(EXIT_FAILURE);
}
//when love_response is 0 A accepted B requests
while(love_response != 0){
//read message from queue
if( msgrcv(msgq, &msg_in, sizeof(msg_in),
-OFFSET, 0) < 1 ){
perror("msgrcv");
exit(EXIT_FAILURE);
}
print_rcvd_msg(msg_in);
//send message to A process and wait for a response
love_response = flirt(msg_in, myself);
printf("2----------------------------\n");
}
//TODO: get ready to terminate
return 0;
}
int flirt(struct mymsg msg, struct person myself)
{
int queue_of_love = msg.mtxt.key_of_love;
pid_t pid_A = msg.mtxt.pid;
struct mymsg love_letter, msg_in;
//create love letter
love_letter.mtype = getpid();
love_letter.mtxt.pid = getpid();
love_letter.mtxt.type = 'B';
love_letter.mtxt.name = myself.name;
love_letter.mtxt.genome = myself.genome;
love_letter.mtxt.key_of_love = -1;
love_letter.mtxt.partner = -1;
//send love letter to A to introduce yourself
if( msgsnd(queue_of_love, &love_letter,
sizeof(love_letter), 0) == -1 ){
perror("B - msg send love");
exit(EXIT_FAILURE);
}
printf("[B:%d] sent<3to [A:%d][mtype:%d][pid:%d]\
[type:%c][gen:%lu][name:%c][love:%d]\n",
(int)getpid(), (int)pid_A,
(int)love_letter.mtype,
(int)love_letter.mtxt.pid,
(int)love_letter.mtxt.type,
(unsigned long)love_letter.mtxt.genome,
love_letter.mtxt.name,
love_letter.mtxt.key_of_love );
//wait for response from A
if( msgrcv(queue_of_love, &msg_in, sizeof(msg_in),
getpid(), 0) == -1 ){
perror("B can't wait for A's response");
exit(EXIT_FAILURE);
}
print_rcvd_msg(msg_in);
//if key of love 0 then accepted love request
printf("1 ----------------------------\n");
return msg_in.mtxt.key_of_love;
}
void print_rcvd_msg(struct mymsg msg)
{
printf("B received [mtype:%lu][pid:%d][type:%c]\
[name:%c][gen:%lu][key<3:%d][pid<3:%d]\n",
msg.mtype,
(int)msg.mtxt.pid,
msg.mtxt.type,
msg.mtxt.name,
msg.mtxt.genome,
msg.mtxt.key_of_love,
(int)msg.mtxt.partner );
}
void print_sent_msg(struct mymsg msg)
{
printf("B sent [mtype:%lu][pid:%d][type:%c]\
[name:%c][gen:%lu][key<3:%d][pid<3:%d]\n",
msg.mtype,
(int)msg.mtxt.pid,
msg.mtxt.type,
msg.mtxt.name,
msg.mtxt.genome,
msg.mtxt.key_of_love,
(int)msg.mtxt.partner );
}
gcc -c header.c
gcc -c personA.c header.c
gcc -c personB.c header.c
gcc -Wall -Wextra -Wconversion -pedantic -std=gnu11 -o A personA.o header.o
gcc -Wall -Wextra -Wconversion -pedantic -std=gnu11 -o B personB.o header.o
gcc -c gestore.c header.c
gcc -Wall -Wextra -Wconversion -std=gnu11 -pedantic -o gestore gestore.o header.o
./gestore
请注意 personB.c 。
中的代码行printf("1----------------------------\n");
printf("2----------------------------\n");
由于错误,第二行无法打印。
提前感谢您的帮助。
output error, stack smashing detected
Valgrind valgrind --leak-check=full -v ./gestore
给出了这个输出:
==8647== HEAP SUMMARY:
==8647== in use at exit: 0 bytes in 0 blocks
==8647== total heap usage: 7 allocs, 7 frees, 4,179 bytes allocated
==8647==
==8647== All heap blocks were freed -- no leaks are possible
==8647==
==8647== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
==8647== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
我应该像这样链接和编译吗?
gcc -c -Wall -Wextra -Wconversion -std=gnu11 -ggdb header.c
gcc -c -Wall -Wextra -Wconversion -std=gnu11 -ggdb personA.c header.c
gcc -c -Wall -Wextra -Wconversion -std=gnu11 -ggdb personB.c header.c
gcc -Wall -pedantic -ggdb -o A personA.o header.o
gcc -Wall -pedantic -ggdb -o B personB.o header.o
gcc -c -Wall -Wextra -Wconversion -std=gnu11 -ggdb gestore.c header.c
gcc -Wall -pedantic -ggdb -o gestore gestore.o header.o
答案 0 :(得分:-2)
我&#39;重大&#39;编辑此答案并删除不再应用的语句,因为OP修改了发布的代码。
注意:修改发布的代码时,一般情况下,请勿修改原始发布的代码,而应将修改后的代码作为编辑发布。对于当前的问题,建议只发布交错代码,也许通过
#if 0
<old code>
#else
<new code>
#endif
===================
在main()function that repeatedly calls
系统中()建议编译步骤启用警告。至少使用这些编译选项:
-Wall -Wextra -Wconversion -pedantic -std=gnu11
注意:上述参数必须在compile
语句中,而不是link
语句。
为了使调试更加轻松,建议compile
和link
选项包括:
-ggdb
此外,main()
函数每次都会执行所有步骤。建议写一个makefile
(并用make
执行它),这样只有那些已经改变的文件才会被重新编译/重新链接
=====
注意:代码省略了消息队列的设置,因此将使用默认值。对于OP应用程序,这些默认值可能不正确。
以下是消息队列的典型设置的剪切/粘贴:
注意:代码来自包含大量消息队列的应用程序taskSelector
选择哪个消息队列
/* initialize the queue attributes */
attr[taskSelector].mq_flags = 0;
attr[taskSelector].mq_maxmsg = 10;
attr[taskSelector].mq_msgsize =
sizeof(struct structITC)
+ dWEB_PAYLOAD_OVERHEAD
+ dMAX_DATA_BLOCK_SIZE;
attr[taskSelector].mq_curmsgs = 0;
=====
发布的代码无法定义:
struct msqid_ds -- oops it is defined in one of the header files
=================
当检查argc
表示用户没有输入所有需要的命令行参数时,代码应输出USAGE
消息并退出。类似于:
fprintf( stderr, "USAGE: %s ..description of all needed parameters..\n", argv[0] );
exit( EXIT_FAILURE );