Автор: Pr1nt
Дата сообщения: 28.05.2010 23:37
Возможно вы сможете помочь мне победить ошибку в учебной задаче:
Вкратце: Программа нахождения математического ожидания для данных находящихся в буфере.
(Выполняется под Ubuntu, GCC 4.4.3)
[more=test.c]#include <stdio.h>
#include <errno.h>
#include <sys/wait.h>
#include <unistd.h>
#include <fcntl.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <ncurses.h> //подключаем библиотеку ncurses
int array[3]; /* Указатель на разделяемую память */
int M=0, W=0;
int myrand(int a, int b) // генерацияслучаынйх чисел
{
return rand()%(b-a)+a;
}
int a=0;
void myprint(int x,int y, char * str){
sleep(0);
move(0,0);
printw("a=%d",a); // вывод строки
a++;
move(x,y);
printw(str); // вывод строки
refresh(); // обновить
}
void p_action (int sig){}
void write_action (int sig){}
/***********************************************************************/
int main(void){
int N, T;
int Xmin=0, Xmax=0, n=1, sum=0;
printf("N=");
scanf("%d",&N);
int L=512;
printf("L=");
scanf("%d",&L);
printf("T=");
scanf("%d",&T);
// инициализация (должна быть выполнена перед использованием ncurses)
initscr();
clear();
myprint(0,0,"");
char str[25];
sprintf(str,"N=%d T=%d", N, T);
myprint(3,0,str);
sprintf(str,"L=%d ",L);
myprint(4,0,str);
sprintf(str,"PID N status ");
myprint(6,0,str);
sprintf(str,"Xmin Xmax. n ");
myprint(6,18,str);
sprintf(str,"expected value ");
myprint(6,36,str);
sprintf(str,"frequency (write/read)");
myprint(6,54,str);
pid_t pids[N];
pid_t ppid;
void p_action (int), write_action (int), read_action (int);
static struct sigaction pact, cact, cract;
int i,k;
/*******************************************/
int shmid; // IPC дескриптор для области разделяемой памяти */
int new = 1; // Флаг необходимости инициализации элементов массива */
char pathname[] = "1.c"; // Имя файла, используемое для генерации ключа. Файл с таким именем должен существовать в текущей директории */
key_t key; // IPC ключ */
// Генерируем IPC ключ из имени файла 06-1a.c в текущей директории и номера экземпляра области разделяемой памяти 0 */
if((key = ftok(pathname,0)) < 0){
sprintf(str,"4Cant generate key");
myprint(0,0,str);
exit(0);
}
/* Пытаемся эксклюзивно создать разделяемую память для сгенерированного ключа, т.е. если для этого ключа она
уже существует, системный вызов вернет отрицательное значение. Размер памяти определяем как размер массива
из трех целых переменных, права доступа 0666 - чтение и запись разрешены для всех */
if((shmid = shmget(key, L*sizeof(int), 0666|IPC_CREAT|IPC_EXCL)) < 0){
/* В случае ошибки пытаемся определить: возникла ли она из-за того, что сегмент разделяемой памяти уже существует или по другой причине */
if(errno != EEXIST){
/* Если по другой причине - прекращаем работу */
sprintf(str,"3Can't create shared memory");
myprint(0,0,str);
exit(0);
} else {
/* Если из-за того, что разделяемая память уже существует, то пытаемся получить ее IPC
дескриптор и, в случае удачи, сбрасываем флаг необходимости инициализации элементов массива */
if((shmid = shmget(key, L*sizeof(int), 0)) < 0){
sprintf(str,"2Can't find shared memory");
myprint(0,0,str);
exit(0);
}
new = 0;
}
}
/* Пытаемся отобразить разделяемую память в адресное пространство текущего процесса. Обратите внимание на то, что для правильного сравнения мы явно преобразовываем значение -1 к указателю на целое.*/
if((array = (int *)shmat(shmid, NULL, 0)) == (int *)(-1)){
sprintf(str,"1Can't attach shared memory");
myprint(0,0,str);
exit(0);
}
/*******************************************/
// создаем процессы
for (i=0; i < N; i++){
switch(pids[i]=fork())
{
case -1 :{
sprintf(str,"fork error");
myprint(0,0,str);
exit(-1);
}
case 0 :{
Xmin = myrand(1,500);
Xmax = myrand(Xmin+10,512);
/*Zadaem obrabotchik v dochernem processe*/
cact.sa_handler = write_action;
sigaction (SIGUSR1, &cact, NULL);
sprintf(str,"%d %d pause",getpid(),i+1);
myprint(i+7,0,str);
pause();
if(i < (int)(N/3) || (N==2 && i==0)){
// процессы записывающие в память
for(;;){
Xmin = myrand(1,500);
Xmax = myrand(Xmin+10,512);
n++;
sum=myrand(Xmin+i,Xmax+i)+myrand(Xmin-i,Xmax+i)+myrand(Xmin+i,Xmax-i);
M = sum / n;
W = a;
sprintf(str,"%d %d write ",getpid(),i+1);
myprint(i+7,0,str);
sprintf(str,"%d %d %d", Xmin, Xmax, n);
myprint(i+7,18,str);
sprintf(str,"%d ", M);
myprint(i+7,36,str);
sprintf(str,"%d ", W);
myprint(i+7,54,str);
array[0]=myrand(Xmin,Xmax);
array[1]=myrand(Xmin,Xmax);
array[3]=myrand(Xmin,Xmax);
sleep(1);
kill (getppid (), SIGUSR2); // посылка родительскому процессу сигнала.
sprintf(str,"%d %d pause ",getpid(),i+1);
myprint(i+7,0,str);
pause();
}
}
else
{
// процессы считывающие и расчитывающие
for(;;){
sprintf(str,"%d %d read/take ",getpid(),i+1);
myprint(i+7,0,str);
sum=myrand(Xmin+i,Xmax+i)+myrand(Xmin-i,Xmax+i)+myrand(Xmin+i,Xmax-i);
M = sum / n;
W = a;
sprintf(str,"%d %d read/take ",getpid(),i+1);
myprint(i+7,0,str);
sprintf(str," - - - ");
myprint(i+7,18,str);
sprintf(str,"%d ", M);
myprint(i+7,36,str);
sprintf(str,"%d ", W);
myprint(i+7,54,str);
sleep(1);
kill (getppid (), SIGUSR2); // посылка родительскому процессу сигнала.
sprintf(str,"%d %d pause ",getpid(),i+1);
myprint(i+7,0,str);
pause();
}
}
i=N;
break;
}
default :
/*Zadaem obrabotchik signala SIGUSR2 v roditel'skom processe*/
pact.sa_handler = p_action;
sigaction (SIGUSR2, &pact, NULL);
if(i==(N-1)){// когда запущены все процссы начинаем работать с буфером.
i=0; // первоначальное значение i для записи данных в пямять
for(;;){
kill (pids[i], SIGUSR1);
i=myrand(0,N); // выбор случайного потока
pause ();
}
// завершение всех процессов
for(i = 0; i < N; i++) waitpid(pids[i], NULL, 0);
/* удаляем разделяемую память из адресного пространства текущего процесса и завершаем работу */
if(shmdt(array) < 0){
sprintf(str,"Cant detach shared memory");
myprint(0,0,str);
exit(-1);
}
}
}
}
endwin(); // завершение работы с ncurses
return 0;
}[/more]
Ошибка: строка 114: error: incompatible types when assigning to type ‘int[3] from type ‘int *