Linux C notes (BOOK UNIX)
江宏深
2023-12-01
Chapter 1: Thread
①
thread functions
1.
pthread_self();
return current thread id
2. thread existing
pthread_exit(void * rval_ptr);
you can get the value of rval_ptr just by
pthread_join(pthread_t tht, void ** rval_ptr)
pthread_cancel(pthread_t thd);
cancel a thread as the thread exits with
PTHREAD_CANCELED in pthread_exit, this function only send a signal but not wait until the thread really exits
3. Control a thread
We can give a function to a thread with which the thread can invoke it when it exits. This
practice is like
atexit in process functions.
pthread_clean_push
pthread_clean_pop
These two functions must be in pairs in your function routines but not in the main function. And one thing should be mentioned as : the routine should not be returned but
exit with pthread_exit(arg);
pthread_detach(pthread_t tid)
Let a thread be detached
4. Thread synchronization of thread
②
thread. synchronics
1. Mutex
i.initiation
pthread_mutex_t variable
pthread_mutex_init() this must be followed with destroy function
pthread_mutex_destroy()
ii. Lock
pthread_mutex_lock() if the mutex is locked wait until ...
pthread_mutex_trylock() return instantly
pthread_unlock()
2. WLock
i. initiation
pthread_rwlook_t
pthread_rwlock_init
pthread_rwlock_destroy
ii. Lock
pthread_rwlock_rdlock
pthread_rwlock_wrlook
pthread_rwlock_unlock
pthread_rwlock_tryrdlock
pthread_rwlock_trywrlock
3. Cond
i. initiation
pthread_cond_t pcndt;
pthread_cond_init(&pcndt, attr);
pthread_cond_destroy(&pcndt);
ii. Wait
pthread_cond_wait(&pcndt, pthread_mutex_t &mt);
pthread_cond_timedwait(....)
pthread_cond_signal(...) evoke a thread waiting for the condition
pthread_cond_broadcast(...) evoke all
threads which are waiting for the condition
example:
before invoking the cond wait function, it's necessary to lock the mutex...so after the invoking of wait, the mutex should be released
③ Thread controling
1. Properties of Thread
i. initiation
pthread_attr_t structure
pthread_attr_init initiate the attr as default value
pthread_attr_destroy
Every thread has its attributes. like attach states which indicates whether the main thread should pay attention to the child thread.
so.
pthread_attr_getdetachstate(...)
pthread_attr_setdetachstate(attr, stat).
stat is either PTHREAD_CREATE_DETACHED or PTHREAD_CREATE_JOINABLE
2. Re-Enter
3. Thread Private Data
i. initiation
pthread_key_t thd_ky_t
pthread_key_create(pthread_key_t,(void(*destructor)))
Chapter 2 : signals
① Register a signal
1.
void * signal(int signo, void (*func)(int));
To ignore a signal to use
signal(signo, SIG_IGN) if it returns
SIG_IGN
, it indicates the signo has been ignored.
2.
kill(pid, signo);
raise(signo);
raise(signo) is equal to kill(getpid(), signo);
pid > 0: send signo to pid process
pid == 0: send signo to all processes who have the same group ids as sender has
pid < 0: send signo to processes who have the gpid as abs(pid)]
pid == -1: send signo to all processes which the sender has privilage to send to
if the signo is 0, the signal is taken as an empty signal, so signal is often set 0 to test whether a process still exists.
3. alarm and pause SIGALRM
alarm(unsigned int seconds);
One process only has one alarm. If a alarm is called after another, the first is replace, the remained will be returned in the return value of the second call.
If the
seconds is 0, the former alarm is canceled.
pause()
The process is suspended util a signal received
setjmp(
jmp_buf jmpbuf
);
longjmp(mark, no);
The no is the return value of setjmp...
4. signal sets
sigset_t *set;
sigemptyset()
sigfillset()
sigadset()
sigdelset()
sigismember()
sigprocmask(int how, const sigset_t * set, sigset_t * oset);
oset : return value showing current signal set
how
SIG_BLOCK, add signal (intersection)
SIG_UNBLOCK, delete signal (union)
SIG_SETMASK, replace current signal set (replacement)
sigpending()
return signals registered pending and unhandled
sigaction act;
sigaction(int signo, const sigaction * newact, struct sigaction * oldact);
replacement of signal()
mind the sa_flags
If it is set : AS_SIGINFO the handle should not be set default, instead
void handler( int signo, siginfo_t * info, void * context)
Default handle is as following :
void handler(ing signo);
sigsuspend()
The process suspended until a registered signal comes and then revert the current signal set to old set
Chapter 3 Advanced I/O
① Blocking I/O
1. Record Locking
This practice can lock partly a file.
fcntl(int fileds, int cmd, struct flock * flkptr);
cmd:
F_GETLK
testing function, testing the lockptr whether can be set, if undoable write old lock into ptr, if doable change the l_type into F_UNLCK
F_SETLK
if the current situation is unlockable return instantly. errno is EACCES or EAGAIN
F_SETLKW
this is blocking parameter.... of SETLK..if the area is unblockable, the caller process
pause until a signal pushed
locktype:
F_RDLCK
F_WRLCK
F_UNCLK
Inner a process, if a lock exists, a new lock can replace the old lock.
How to test a lock:
{
struct flock lock;
lock.l_type = type;
lock.l_start = offset;
lock.l_whence = whence;
lock.l_len = len;
if(fcntl(fd, F_GETLCK,&lock) < 0)
{
//error
}
if(lock.l_type == F_UNLCK)
{
return false;
}
}
Release a lock
{
when the file handle is released, all locks binded to it will be automatically released too.
}
lock sharing:
child process never inherit parents' lock
Chapter 4 Process Msg
①:pipe
1. pipe
semiduplex.
pipe(int fileds[2]);
Two file descriptors, one for writering , one for reading
the direction seems fileds[1] --> fileds[0], write(1), read(0)
2. popen
popen(cmdstring, type);
pclose()
cmdstring is a cmd like "ls -a" which runs in shell
type is direction shows input or output
note:
this pipe has also single direction
3. coprocess
②:named pipe
③:IPC
(msg queue, semaphore
, shared memory)
1. queue
msgget(key_t key, int flag);
This function creates or retrieve a msg from the msg queue.
If
msgflg specifies both
IPC_CREAT and
IPC_EXCL and a message queue already exists for
key, then
msgget() fails with
errno set to
EEXIST
A new message queue is created if
key has the value
IPC_PRIVATE .
And if the key is not
IPC_PRIVATE but no queue with the given key exists, new queue will be created
.
If succeeds, return queue id, vice versa.
msgctl(int msqid, int cmd, struct msgqid_ds * buf);
IPC_STAT
retrieve the msgque stuctor into the buf
IPC_SET
change the structor related to the id
IPC_RMID
remove the msg from queue by given id
msgsnd(int msqid, const void * ptr, size_t nbytes, int flag);
msgrecv(int msqid, const void * ptr, size_t nbytes, int flag);
Mind the ptr, ptr is a structure as following
struct msgbuf
{
long mtype;
/* message type, must be > 0 */
char mtext[n];
/* message data */
};
This size of mtext is specified by nbytes..
If
flag is set IPC_NOWAIT it functions nonblockingly
as for msgrecv, when received msg is longer than nbytes, if flag is set MSG_NOERROR, the msg will be truncated, but if no flag set MSG_NOERROR, error
Chapter 5 SOCKET Summaries
Chapter 6 File And Directory
① Dir Operation
#include
#include
#include
#include
int main()
{
DIR * pDir = NULL;
struct dirent * pDirent = NULL;
pDir =
opendir("./pcapfiles/");
while((pDirent =
readdir(pDir)) != NULL)
{
char szPath[1024];
struct stat buf;
sprintf(szPath, "./pcapfiles/%s",pDirent->d_name);
stat (szPath,&buf);
if(
S_ISDIR(buf.st_mode))
{
printf("d_name: %sn",pDirent->d_name);
}
}
}
#NOTE this example lists all files and dirs in a given dir, mind the macro
S_ISDIR
can judge a
#path is a dir or a file