linuxc的函數
把Signal(16, stop); 和Waiting(); 調換順序試試,我現在沒條件就不幫你試了
『貳』 Linux C write函數
好隱蔽的一個錯誤!! if ((fd=open(pathname, FLAGS, MODE)==-1)) 這句,括弧的位置錯誤了
應該是: if ( (fd=open(pathname, FLAGS, MODE))==-1)
原寫法,導致fd值為0,成了標准輸入(終端)了,所以,lseek就會一直報錯!
『叄』 LinuxC語言頭裡面的ERROR函數怎麼使用
errno會返回一個數字,每個數字代表一個錯誤類型。詳細的可以查看頭文件。/usr/include/asm/errno.h
如何把errno的數字轉換成相應的文字說明?
方式一:可以使用strerrno函數
char
*strerror(int
errno)
使用方式如下:
fprintf(stderr,"error
in
CreateProcess
%s,
Process
ID
%d
",strerror(errno),processID)
將錯誤代碼轉換為字元串錯誤信息,可以將該字元串和其它的信息組合輸出到用戶界面。
註:假設processID是一個已經獲取了的整形ID
方式二:使用perror函數
void
perror(const
char
*s)
函數說明
perror
(
)用來將上一個函數發生錯誤的原因輸出到標准錯誤(stderr),參數s
所指的字元串會先列印出,後面再加上錯誤原因
字元串。此錯誤原因依照全局變數
errno
的值來決定要輸出的字元串。
另外並不是所有的c函數調用發生的錯誤信息都會修改errno。例如gethostbyname函數。
errno是否是線程安全的?
errno是支持線程安全的,而且,一般而言,編譯器會自動保證errno的安全性。
我們看下相關頭文件
/usr/include/bits/errno.h
會看到如下內容:
#
if
!defined
_LIBC
||
defined
_LIBC_REENTRANT
/*
When
using
threads,
errno
is
a
per-thread
value.
*/
#
define
errno
(*__errno_location
())
#
endif
#
endif
/*
!__ASSEMBLER__
*/
#endif
/*
_ERRNO_H
*/
也就是說,在沒有定義__LIBC或者定義_LIBC_REENTRANT的時候,errno是多線程/進程安全的。
為了檢測一下你編譯器是否定義上述變數,不妨使用下面一個簡單程序。
#include
<stdio.h>
#include
<errno.h>
int
main(
void
)
{
#ifndef
__ASSEMBLER__
printf(
"Undefine
__ASSEMBLER__/n"
);
#else
printf(
"define
__ASSEMBLER__/n"
);
#endif
#ifndef
__LIBC
printf(
"Undefine
__LIBC/n"
);
#else
printf(
"define
__LIBC/n"
);
#endif
#ifndef
_LIBC_REENTRANT
printf(
"Undefine
_LIBC_REENTRANT/n"
);
#else
printf(
"define
_LIBC_REENTRANT/n"
);
#endif
return
0;
}
『肆』 紅帽linux中C語言編程如何調用數學函數
紅帽linux中C語言編程調用數學函數參考案例如下所示:
當需要調用函數的個數比較少時,可以直接在main函數中包含該文件,比如一個文件夾下包含add.c和main.c文件。
文件add.c定義兩個整數相加的函數,code如下:#include
『伍』 send的Linux C 函數
經套接字傳送消息
相關函數
sendto,sendmsg,recv,recvfrom,recvmsg,socket
表頭文件
#include < sys/socket.h >
定義函數
ssize_t send (int s,const void *msg,size_t len,int flags);
參數說明
第一個參數指定發送端套接字描述符;
第二個參數指明一個存放應用程式要發送數據的緩沖區;
第三個參數指明實際要發送的數據的字元數;
第四個參數一般置0。
函數說明
send() 用來將數據由指定的 socket 傳給對方主機。使用 send 時套接字必須已經連接。send 不包含傳送失敗的提示信息,如果檢測到本地錯誤將返回-1。因此,如果send 成功返回,並不必然表示連接另一端的進程接收數據。所保證的僅是當send 成功返回時,數據已經無錯誤地發送到網路上。
對於支持為報文設限的協議,如果單個報文超過協議所支持的最大尺寸,send 失敗並將 errno 設為 EMSGSIZE ;對於位元組流協議,send 會阻塞直到整個數據被傳輸。
flags 參數有如下的選擇:
MSG_DONTROUTE 勿將數據路由出本地網路
MSG_DONTWAIT 允許非阻塞操作(等價於使用O_NONBLOCK)
MSG_EOR 如果協議支持,此為記錄結束
MSG_OOB 如果協議支持,發送帶外數據
MSG_NOSIGNAL 禁止向系統發送異常信息
返回值
成功則返回實際傳送出去的字元數,失敗返回-1,錯誤原因存於errno 中。
錯誤代碼
EBADF 參數 s 非法的 socket 處理代碼。
EFAULT 參數中有一指針指向無法存取的內存空間。
WNOTSOCK 參數 s 為一文件描述詞,非 socket。
EINTR 被信號所中斷。
EAGAIN 此動作會令進程阻斷,但參數 s 的 socket 為不可阻斷的。
ENOBUFS 系統的緩沖內存不足。
EINVAL 傳給系統調用的參數不正確。
『陸』 在Linux下,在C中怎麼調用C++的庫函數
調用C++函數庫,一般不能直接調用,需要將C++庫轉換成C介面輸出,方可以使用C調用
將 C++ 函數聲明為``extern "C"''(在你的 C++ 代碼里做這個聲明),然後調用它(在你的 C 或者 C++ 代碼里調用)。例如:
// C++ code:
extern "C" void f(int);
void f(int i)
{
// ...
}
然後,你可以這樣使用 f():
/* C code: */
void f(int);
void cc(int i)
{
f(i);
/* ... */
}
當然,這招只適用於非成員函數。如果你想要在 C 里調用成員函數(包括虛函數),則需要提供一個簡單的包裝(wrapper)。例如:
// C++ code:
class C
{
// ...
virtual double f(int);
};
extern "C" double call_C_f(C* p, int i) // wrapper function
{
return p->f(i);
}
然後,你就可以這樣調用 C::f():
/* C code: */
double call_C_f(struct C* p, int i);
void ccc(struct C* p, int i)
{
double d = call_C_f(p,i);
/* ... */
}
如果你想在 C 里調用重載函數,則必須提供不同名字的包裝,這樣才能被 C 代碼調用。例如:
// C++ code:
void f(int);
void f(double);
extern "C" void f_i(int i) { f(i); }
extern "C" void f_d(double d) { f(d); }
然後,你可以這樣使用每個重載的 f():
/* C code: */
void f_i(int);
void f_d(double);
void cccc(int i,double d)
{
f_i(i);
f_d(d);
/* ... */
}
注意,這些技巧也適用於在 C 里調用 C++ 類庫,即使你不能(或者不想)修改 C++ 頭文件。
再看下面的例子:
aa.cxx
#include "aa.h"
int sample::method()
{
cout<<"method is called!\n";
}
aa.h
#include
using namespace std;
class sample
{
public:
int method();
};
將上面的兩個文件生成動態庫libaa.so放到 /usr/lib目錄下,編譯命令如下
sudo g++ -fpic -shared -g -o /usr/lib/libaa.so aa.cxx -I ./
由於在C中不能識別類,所以要將上面類的成員函數封裝成C介面函數輸出,下面進行封裝,將輸出介面轉換成C介面。
mylib.cxx
#include "add.h"
#ifndef _cplusplus
#define _cplusplus
#include "mylib.h"
#endif
int myfunc()
{
sample ss;
ss.method();
return 0;
}
mylib.h
#ifdef _cplusplus
extern "C"
{
#endif
int myfunc();
#ifdef _cplusplus
}
#endif
在linux下,gcc編譯器並沒用變數_cplusplus來區分是C代碼還是C++代碼,如果使用gcc編譯器,這里我們可以自己定義一個變數_cplusplus用於區分C和C++代碼,所以在mylib.cxx中定義了一個變數_cplusplus用於識別是否需要「extern "C"」將函數介面封裝成C介面。但是如果使用g++編譯器則不需要專門定義_cplusplus,編譯命令如下:
g++ -fpic -shared -g -o mylib.so mylib.cxx -la -I ./
main.c
#include
#include
#include "mylib.h"
int
main()
{
int (*dlfunc)();
void *handle; //定義一個句柄
handle = dlopen("./mylib.so", RTLD_LAZY);//獲得庫句柄
dlfunc = dlsym(handle, "myfunc"); //獲得函數入口
(*dlfunc)();
dlclose(handle);
return 0;
}
編譯命令如下:
gcc -o main main.c ./mylib.so -ldl
下面就可以執行了。
需要說明的是,由於main.c 和 mylib.cxx都需要包含mylib.h,並且要將函數myfunc封裝成C介面函數輸出需要「extern "C"」,而C又不識別「extern "C"」,所以需要定義_cplusplus來區別處理mylib.h中的函數myfunc。
在main.c的main函數中直接調用myfunc()函數也能執行,這里介紹的是常規調用庫函數的方法。
『柒』 linux c signal函數
是第二次調用的時候輸出的,第一次調用只是綁定了SIGUSR1的信號處理函數,不會進入該處理函數
為什麼會有這樣的輸出呢?
signal函數是將信號與處理函數進行綁定,成功綁定則返回綁定之前的信號處理函數。那麼來看看你的代碼,第一次調用將sig_fun1綁定,無輸出;第二次調用將sig_fun2綁定,也就是把sig_fun1替換下來,並且你還調用了它,參數為30,所以會有那樣的輸出。
該如何改呢?
其實你並沒有涉及到linux的信號處理機制,光綁定是不夠的,還需要發信號給它,才能真正進入信號處理過程。給你一個示例代碼吧
#include<signal.h>
#include<stdlib.h>
#include<stdio.h>
#include<unistd.h>
void sig_fun2(int signo)
{
printf("in sig_fun2:%d\n", signo);
}
void sig_fun1(int signo)
{
printf("in sig_fun1:%d\n", signo);
}
int main()
{
unsigned long i;
if (signal(SIGUSR1, sig_fun1) == SIG_ERR)
{
printf("signal fun1 error\n");
exit(1);
}
sleep(15);
(signal(SIGUSR1, sig_fun2))(30);
sleep(15);
printf("done\n");
return 0;
}
/****************************C 代碼完,下面是如何運行***************************/
首先編譯,假設生成可執行程序為test
然後運行,我用的是後台運行: nohup ./test>output.txt &
注意,這種方法要將輸出重定向到文件output.txt(名字無所謂),然後你會看到一個數字,就是pid進程號
最後,在15秒之內發送信號:kill -SIGUSR1 進程號
現在你就可以打開output.txt看輸出結果了。如果用sleep的話會被打斷,所以只有兩個輸出加上替換處理函數時的輸出共3個,也可以換成 int n=15;while(n--)sleep(1);
-------------------------------------------------------------
怎麼樣,加分吧
-------------------------------------------------------------
1.我就是想問第二次綁定sig_fun2的時候,調用了第一次綁定的sig_fun1么?
調用了, (signal(SIGUSR1, sig_fun2))(30);就是這一句, signal(SIGUSR1, sig_fun2)是個函數指針,你這樣寫就是調用它了,但是這和信號處理沒關系,寫成signal(SIGUSR1, sig_fun2);就可以了
這就是你所說的成功則返回綁定之前的函數???
對
那當時綁定sig_fun1的時候,返回之前的處理函數是什麼??
這個就是系統默認的了,比如SIGINT就是你ctrl+c取消程序執行發送的信號,它的處理函數就是結束程序的一系列動作,不過SIGUSR1是留給用戶自定義的信號,系統默認應該是啥也不做的一個函數,例如void fun(int signo){},你也可以第一次綁定的時候就調用試試看對不對
2.還有我在看signal函數定義的時候,void(//...)(int) 最後傳入的這個int整形參數就是我們自定義sig_fun()中所接收的30么??我看例子裡面有的signal(SIGINT,myfunc);也沒有帶參數啊,搞不懂
是你理解錯了,signal函數只是綁定,沒涉及到調用綁定函數,不用帶參數,信號處理函數不是像你這樣調用的。callback回調你知道吧,就是先做好一個函數或過程放著,事件觸發的時候才調用。那個30是你用普通函數調用的方式時的參數,跟信號處理一點關系也沒有,你用60,70也沒半毛錢關系。我猜你是想要調用信號處理函數,然後迷糊了,其實我上面說的「kill -SIGUSR1 進程號」就是觸發程序調用該處理函數的信號,這和kill -9 殺死進程一個道理,只不過處理函數不同,結果不一樣。ctrl+c也可以用信號的方式發送,kill -2 進程號,或者 kill -SIGINT 進程號
另外,站長團上有產品團購,便宜有保證
『捌』 linux下C語言有沒有定時調用的函數
你是指延遲函數還是定時調用,比如到11:12:13秒執行某個函數?
如果是延時函數用
usleep(usec);//微妙
sleep(sec);//秒
如果是定時執行的話,你只能開個線程或while,每隔1s判斷下當前系統時間,
structtm*ptm;
longts;
inty,m,d,h,n,s;
ts=time(NULL);
ptm=localtime(&ts);
y=ptm->tm_year+1900;//年
m=ptm->tm_mon+1;//月
d=ptm->tm_mday;//日
h=ptm->tm_hour;//時
n=ptm->tm_min;//分
s=ptm->tm_sec;//秒
照著上面的格式組成字元串進行判斷,到點了就執行就可以了
『玖』 linux下c語言環境變數操作的幾個相關函數
這幾個函數的原型在<stdio.h>中定義
/* Return the value of envariable NAME, or NULL if it doesn't exist. */
extern char *getenv (__const char *__name) __THROW __nonnull ((1)) __wur;
/* The SVID says this is in <stdio.h>, but this seems a better place. */
/* Put STRING, which is of the form "NAME=VALUE", in the environment.
If there is no `=', remove NAME from the environment. */
extern int putenv (char *__string) __THROW __nonnull ((1));
/* Set NAME to VALUE in the environment.
If REPLACE is nonzero, overwrite an existing value. */
extern int setenv (__const char *__name, __const char *__value, int __replace)
__THROW __nonnull ((2));
/* Remove the variable NAME from the environment. */
extern int unsetenv (__const char *__name) __THROW __nonnull ((1));
『拾』 Linux C語言 malloc 函數
Queue的定義在哪
要轉換類型 = (*類型)malloc(sizeof(類型))