I am trying to simply run two ncurse windows using pthread. The code i have written is as follows:
#include<stdio.h>
#include<pthread.h>
#include<ncurses.h>
#include<sys/ioctl.h>
#include<string.h>
#include<unistd.h>
struct winsize w;
WINDOW *win1,*win2;
void createWin1(void){
while(1){
char buffer[1024];
win1=newwin(0,0,40,50);
box(win1,0,0);
wrefresh(win1);
sleep(1);
}
}
void createWin2(void){
while(1){
win2=newwin(40,50,40,60);
box(win2,0,0);
wrefresh(win2);
sleep(1);
}
}
void main()
{ initscr();
noecho();
cbreak();
start_color();
use_default_colors();
init_pair(1,COLOR_WHITE, -1);
pthread_t p1,p2;
pthread_create(&p1,NULL,(void *)createWin1,NULL);
pthread_create(&p2,NULL,(void *)createWin2,NULL);
pthread_join(p1,NULL);
pthread_join(p2,NULL);
}
Now the problem is I cant run two windows in parallel .This will show unexpected output. Can anyone please help me to find out the issue in my code.
The approach used in the sample code cannot work reliably because curses uses static/global variables. You can either setup mutexes around the ncurses calls (to ensure that input or output from one thread is separate from the others), or compile (there are few packages) the version with rudimentary threading support as a starting point.
In the ncurses FAQ, start with Why does (fill in the blank) happen when I use two threads?
i think you have to include #include ncurses.h in your source code ?
the declaration struct winsize w; seems to create an incomplete type
the variable flag is not declared in the scope of the function createWin1()
try to paste the entire code if possible
i've an error of including panel.h
i've a problem with my opensuse right now, i found some people with the same problem so i'm looking for that, i mean about including panel.h
error 'row' was not declared in this scope
in win1=newwin(w.ws_row-row
I'm trying to find the paramiters you used for the variable w "ws_row-row" is it correct, try to search the content of WINDOW struct ??
i think you have to define newwin correctely with good values
WINDOW * win = newwin(nlines, ncols, y0, x0);
http://hughm.cs.ukzn.ac.za/~murrellh/os/notes/ncurses.html#window
still four errors in my side
main has to return a value , i declared it int main, and i return zero, the compiler complain about that
there is some errors about conversion in pthread_create
you function have to be declared void* createWin1(void*)
and not void createWin1(void)
do you have any compilation errors in your side or not ?
i'm trying to help you i'm not a specialist about ncurses
now the compilation is ok but i have linker errors
undefined reference to newwin .....
it's a library problem, think we are not far from: https://github.com/mariostg/nffm/issues/2
i compiled with g++ -pthread test.c for now, i w'll look again tomorow
Related
Can a program be written without main() function?
I have written this code and saved a filename as withoutmain.c
and getting an error as
undefined reference to 'WinMain#16'"
My code
#include<stdio.h>
#include<windows.h>
extern void _exit(register int code);
_start(){
int retval;
retval=myFunc();
_exit(retval);
}
int myFunc(void){
printf("Hiii Pratishtha");
return 0;
}
Please provide me the solution of this problem and also the proper memory construction of code and what is happening at the compiler end of this program.
Thank you!
Can a program be written without main() function?
Yes there can be a C program without a main function.
I would suggest two solutions.......
1) Using a macro that defines main
#include<stdio.h>
#include<windows.h>
#define _start main
extern void _exit(register int code);
int myFunc(void){
printf("Hiii Pratishtha");
return 0;
}
int _start(){
int retval;
retval=myFunc();
_exit(retval);
}
2) Using Entry Point (Assuming you are using visual studio)
To set this linker option in the Visual Studio development environment
/ENTRY:function
A function that specifies a user-defined starting address for an .exe file or DLL.
Open the project's Property Pages dialog box. For details, see
Setting Visual C++ Project Properties.
LClick the Linker folder.
Click the Advanced property page.
Modify the Entry Point property.
OR
if you are using gcc then
-Wl,-e_start
the -Wl,... thing passes arguments to the linker, and the linker takes a -e argument to set the entry function
I am working on Ubuntu these days. When I compiled my C program using gcc, it is giving the error conio.h doesn't exists.
I want to use clrscr() and getch() function.
Can you please tell me the substitute of this header file in linux.
The getch() function can be found in curses.h (library "curses"). The same library offers functions to clear the screen. Check out these links:
http://linux.die.net/man/3/getch
http://linux.die.net/man/3/erase
system("clear"); can be used in linux instead of clrscr();
# include <curses.h>
int erase(void);
int werase(WINDOW *win);
int clear(void);
int wclear(WINDOW *win);
int clrtobot(void);
int wclrtobot(WINDOW *win);
int clrtoeol(void);
int wclrtoeol(WINDOW *win);
DESCRIPTION
The erase and werase routines copy blanks to every position in
the window, clearing the screen.
I'm guessing this question was repeatedly downvoted because it implies a poor understanding of basic C language features and/or that OP is simply copying/pasting code into editor/IDE.
Similarly, just use system("exit"); within your code:
#include<stdlib.h>
main()
{
system("clear"); //clears the screen
}
Checking the man-pages shows:
SYSTEM(3) Linux Programmer's Manual SYSTEM(3)
NAME
system - execute a shell command
SYNOPSIS
#include <stdlib.h>
int system(const char *command);
DESCRIPTION
system() executes a command specified in command by calling /bin/sh -c
command, and returns after the command has been completed.
During execution of the command, SIGCHLD will be blocked, and SIGINT
and SIGQUIT will be ignored.
It could also be the case that this question is a possible duplicate of the following:
How to implement getch() function of C in Linux?
Why can't I find <conio.h> on Linux?
GNU/Linux replacements for Turbo C functions `clrscr` and `cprintf`
Function clrscr in C and C++
"UNDEFINED REFRENCE TO clrscr();"
Substitute for getch(), gotoxy(), delay(), clrscr()
What is Equivalent to getch() & getche() in Linux?
Finally, take a look at the following for more details and examples:
http://tldp.org/HOWTO/NCURSES-Programming-HOWTO/scanw.html#GETCHCLASS
http://ubuntuforums.org/showthread.php?t=549023
Apparently you didn't try googling.
There are no direct alternatives.
This blog post: http://wesley.vidiqatch.org/code-snippets/alternative-for-getch-and-getche-on-linux/ provides you with alternatives for getch() and getche()
Alternatively you can use libncurses to do what you want: http://tech.dir.groups.yahoo.com/group/linux/message/29221
curses.h is an alternative for conio.h.
install build-essentials and install libncurses5-dev.
Then you can work with that functions.
[http://ubuntuforums.org/showthread.php?t=880601][1]
I was tinkering around with some codes; after i installed ncurses, I inserted these codes:
#include <stdio.h>
#include <ncurses.h>
main ()
{
system ("clear");
getchar ();
}
There is another way to do it through C code instead system call.
void clrscr(void) {
fprintf(stdout, "\033[2J\033[0;0f");
fflush(stdout);
}
I found it long time ago and I've checked it on raspbian successfully.
And also:
void gotoxy(int x, int y) {
printf("%c[%d;%df",0x1B, y, x);
}
I hope it helps you.
Regards.
In G++ Compiler, we use system("clear") function defined in stdlib.h header File
#include<iostream>
#include<stdlib.h>
int main() {
std::cout<<"Hello Aliens:";
system("clear");
}
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
undefined reference to pthread_create in linux (c programming)
I am trying to implement Thread chain in Ubuntu in C. When I compile the following code, I get the errors of Undefined reference to these thread library function even though I have added the header file.I am also getting segmentation fault error. Why is that? I am not accessing some uninitialized memory anywhere in program. Here is the code:
#include <stdio.h>
#include<stdlib.h>
#include <pthread.h>
void* CreateChain(int*);
int main()
{
int num;
pthread_t tid;
scanf("Enter the number of threads to create\n %d",&num);
pthread_create(&tid,NULL,CreateChain,&num);
pthread_join(tid,NULL);
printf("Thread No. %d is terminated\n",num);
return 0;
}
void* CreateChain(int* num )
{
pthread_t tid;
if(num>0)
{
pthread(&tid,NULL,CreateChain,num);
pthread_join(tid,NULL);
printf("Thread No. %d is terminated\n",*num);
}
else
return NULL;
return NULL;
}
I am getting following warnings and the Scanf prompt is not appearing for some reason.
Regards
The pthread.h header file provides a forward declaration of pthread functions. This tells the compiler than these functions exist and have a certain signature. It doesn't however tell the linker anything about where to find these functions at runtime.
To allow the linker to resolve these calls (decide where to jump to inside your code or in a different shared object), you need to link against the appropriate (pthread) library by adding
-pthread
to your build command line.
[Note that it is also possible to use -lpthread. This previous question expains why -pthread is preferable.]
There are various other issues with the code that will be worthy of attention
The scanf line should be split into printf("Enter number of threads\n");scanf("%d", &num); to get the user prompt displayed
The signature of CreateChain is wrong - it should take a void* argument instead. You can always do something like int num = *(int*)arg; inside the function to retrieve the number of threads.
The logic inside CreateChain looks wrong. You currently compare a pointer against 0 - I presume you mean to compare the number of threads instead? Also, if you don't decrement the number of threads to create somewhere, you'll end up with code that creates threads forever (or until you run out of handles depending on how the different threads get scheduled).
Try compiling like this below :
gcc -Wall -pthread test.c -o test.out
-pthread is an option to tell linker explicitly to resolve the symbols related to <pthread.h>
add -lpthread
gcc -o test test.c -lpthread
I had a problem with a part of my code, which after some iterations seemed to read NaN as value of a double of a struct. I think I found the error, but am still wondering why gcc (version 3.2.3 on a embedded Linux with busybox) did not warn me. Here are the important parts of the code:
A c file and its header for functions to acquire data over USB:
// usb_control.h
typedef struct{
double mean;
short *values;
} DATA_POINTS;
typedef struct{
int size;
DATA_POINTS *channel1;
//....7 more channels
} DATA_STRUCT;
DATA_STRUCT *create_data_struct(int N); // N values per channel
int free_data_struct(DATA_STRUCT *data);
int aqcu_data(DATA_STRUCT *data, int N);
A c and header file with helper function (math, bitshift,etc...):
// helper.h
int mean(DATA_STRUCT *data);
// helper.c (this is where the error is obviously)
double mean(DATA_STRUCT *data)
{
// sum in for loop
data->channel1->mean = sum/data->N;
// ...7 more channels
// a printf here displayed the mean values corretly
}
The main file
// main.c
#include "helper.h"
#include "usb_control.h"
// Allocate space for data struct
DATA_STRUCT *data = create_data_struct(N);
// get data for different delays
for (delay = 0; delay < 500; delay += pw){
acqu_data(data, N);
mean(data);
printf("%.2f",data->channel1->mean); // done for all 8 channels
// printf of the mean values first is correct. Than after 5 iterations
// it is always NaN for channel1. The other channels are displayed correctly;
}
There were no segfaults nor any other missbehavior, just the NaN for channel1 in the main file.
After finding the error, which was not easy, it was of course east to fix. The return type of mean(){} was wrong in the definition. Instead of double mean() it has to be int mean() as the prototype defines. When all the functions are put into one file, gcc warns me that there is a redefinition of the function mean(). But as I compile each c file seperately and link them afterwards gcc seems to miss that.
So my questions would be. Why didn't I get any warnings, even non with gcc -Wall? Or is there still another error hidden which is just not causing problems now?
Regards,
christian
When each .c file is compiled separately, the only information the compiler knows is the function prototype you have given.
Because every file is compiled separately, there is no way the compiler process of main.c knows the definition of mean in helper.c is wrong.
After the .c file is compiled, the signature will be stripped, so the linker cannot know the mean is wrong either.
A simple fix is always include the interface .h file in the implementation .c file
// in helper.c:
#include "helper.h"
double mean(DATA_STRUCT *data);
Then the compiler process of helper.c will notice that inconsistent type and warn you.
A mean usually is a real value so double is ok. Here you define mean as returning double, but the prototype says int mean(...).
The only way gcc can be aware of the fact that there's a redefinition, is if the redefinition occurs for real... When you compile files separately likely the mean prototype is missing... it is not shown in your code fragment at least: you should include helper.h also into helper.c. Doing so, gcc -c helper.c must give you a warning. I have gcc 4.3.2, but I am almost sure it must be so also for the version you have. In the main, you just use mean, so here the gcc trusts what is said in helper.h. When you link, there is no more information about the size of arguments and returning value, and bad things happen (like reading an int as a double).
Another detail: you say you get NaN for an int of the struct... well, in the struct there's a double, and int can't be NaN!
I've got some C code I'm targeting for an AVR. The code is being compiled with avr-gcc, basically the gnu compiler with the right backend.
What I'm trying to do is create a callback mechanism in one of my event/interrupt driven libraries, but I seem to be having some trouble keeping the value of the function pointer.
To start, I have a static library. It has a header file (twi_master_driver.h) that looks like this:
#ifndef TWI_MASTER_DRIVER_H_
#define TWI_MASTER_DRIVER_H_
#define TWI_INPUT_QUEUE_SIZE 256
// define callback function pointer signature
typedef void (*twi_slave_callback_t)(uint8_t*, uint16_t);
typedef struct {
uint8_t buffer[TWI_INPUT_QUEUE_SIZE];
volatile uint16_t length; // currently used bytes in the buffer
twi_slave_callback_t slave_callback;
} twi_global_slave_t;
typedef struct {
uint8_t slave_address;
volatile twi_global_slave_t slave;
} twi_global_t;
void twi_init(uint8_t slave_address, twi_global_t *twi, twi_slave_callback_t slave_callback);
#endif
Now the C file (twi_driver.c):
#include <stdint.h>
#include "twi_master_driver.h"
void twi_init(uint8_t slave_address, twi_global_t *twi, twi_slave_callback_t slave_callback)
{
twi->slave.length = 0;
twi->slave.slave_callback = slave_callback;
twi->slave_address = slave_address;
// temporary workaround <- why does this work??
twi->slave.slave_callback = twi->slave.slave_callback;
}
void twi_slave_interrupt_handler(twi_global_t *twi)
{
(twi->slave.slave_callback)(twi->slave.buffer, twi->slave.length);
// some other stuff (nothing touches twi->slave.slave_callback)
}
Then I build those two files into a static library (.a) and construct my main program (main.c)
#include
#include
#include
#include
#include "twi_master_driver.h"
// ...define microcontroller safe way for mystdout ...
twi_global_t bus_a;
ISR(TWIC_TWIS_vect, ISR_NOBLOCK)
{
twi_slave_interrupt_handler(&bus_a);
}
void my_callback(uint8_t *buf, uint16_t len)
{
uint8_t i;
fprintf(&mystdout, "C: ");
for(i = 0; i < length; i++)
{
fprintf(&mystdout, "%d,", buf[i]);
}
fprintf(&mystdout, "\n");
}
int main(int argc, char **argv)
{
twi_init(2, &bus_a, &my_callback);
// ...PMIC setup...
// enable interrupts.
sei();
// (code that causes interrupt to fire)
// spin while the rest of the application runs...
while(1){
_delay_ms(1000);
}
return 0;
}
I carefully trigger the events that cause the interrupt to fire and call the appropriate handler. Using some fprintfs I'm able to tell that the location assigned to twi->slave.slave_callback in the twi_init function is different than the one in the twi_slave_interrupt_handler function.
Though the numbers are meaningless, in twi_init the value is 0x13b, and in twi_slave_interrupt_handler when printed the value is 0x100.
By adding the commented workaround line in twi_driver.c:
twi->slave.slave_callback = twi->slave.slave_callback;
The problem goes away, but this is clearly a magic and undesirable solution. What am I doing wrong?
As far as I can tell, I've marked appropriate variables volatile, and I've tried marking other portions volatile and removing the volatile markings. I came up with the workaround when I noticed removing fprintf statements after the assignment in twi_init caused the value to be read differently later on.
The problem seems to be with how I'm passing around the function pointer -- and notably the portion of the program that is accessing the value of the pointer (the function itself?) is technically in a different thread.
Any ideas?
Edits:
resolved typos in code.
links to actual files: http://straymark.com/code/ [test.c|twi_driver.c|twi_driver.h]
fwiw: compiler options: -Wall -Os -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -mmcu=atxmega128a1 -DF_CPU=2000000UL
I've tried the same code included directly (rather than via a library) and I've got the same issue.
Edits (round 2):
I removed all the optimizations, without my "workaround" the code works as expected. Adding back -Os causes an error. Why is -Os corrupting my code?
Just a hunch, but what happens if you switch these two lines around:
twi->slave.slave_callback = slave_callback;
twi->slave.length = 0;
Does removing the -fpack-struct gcc flag fix the problem? I wonder if you haven't stumbled upon a bug where writing that length field is overwriting part of the callback value.
It looks to me like with the -Os optimisations on (you could try combinations of the individual optimisations enabled by -Os to see exactly which one is causing it), the compiler isn't emitting the right code to manipulate the uint16_t length field when its not aligned on a 2-byte boundary. This happens when you include a twi_global_slave_t inside a twi_global_t that is packed, because the initial uint8_t member of twi_global_t causes the twi_global_slave_t struct to be placed at an odd address.
If you make that initial field of twi_global_t a uint16_t it will probably fix it (or you could turn off struct packing). Try the latest gcc build and see if it still happens - if it does, you should be able to create a minimal test case that shows the problem, so you can submit a bug report to the gcc project.
This really sounds like a stack/memory corruption issue. If you run avr-size on your elf file, what do you get? Make sure (data + bss) < the RAM you have on the part. These types of issues are very difficult to track down. The fact that removing/moving unrelated code changes the behavior is a big red flag.
Replace "&my_callback" with "my_callback" in function main().
Because different threads access the callback address, try protecting it with a mutex or read-write lock.
If the callback function pointer isn't accessed by a signal handler, then the "volatile" qualifier is unnecessary.