How Ubunt u implements the cp function
ps: copy the content of one file to another file, test: text, image, video
#include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <string.h> int main(int argc, char*argv[]) { if(argc<3) { printf("Missing parameters!\n"); return -1; } char srcFile[1024]; char destDir[1024]; strcpy(srcFile, argv[1]); strcpy(destDir, argv[2]); char destFile[1024]; strcpy(destFile, destDir); char *p = strrchr(srcFile, '/'); strcat(destFile, p); int rfd, wfd; rfd = open(srcFile, O_RDONLY); if(rfd < 0) { perror("open"); return -1; } wfd = open(destFile, O_CREAT|O_WRONLY|O_TRUNC, 0777); if(wfd < 0) { perror("open"); return -1; } char buff[1024]; int ret; while(1) { ret = read(rfd, buff, 1024); if(ret<0) { perror("read"); break; } else if (ret == 0) { break; } ret = write(wfd, buff, ret); if(ret < 0) { perror("write"); break; } } close(rfd); close(wfd); return 0; }
Function with parameters: int main(int argc, char* argv[])
function name: access
Function: Determine the access permission of the file
Usage: int access(const char *filename, int amode);
Function name: lseek
off_t lseek(int fd, off_t offset, int whence);
fd: file descriptor
offset: offset bytes
whence: the position of the file pointer (SEEK_SET: start position, SEEK_CUR: current position, SEEK_END: end address)
Return value: return offset
ps: You can use the lseek function to calculate the file size;
process
1.fork();
Function: Split a child process out. Once the fork function is called to create a child process, it will transfer all the resources of the parent process, including:
The code segment, data segment, heap, stack, buffer, and cpu state are all copied to the child process, so the child process starts executing from the next line of code in the fork.
Return value: The parent process returns the process ID of the child process
child process returns 0
return -1 on failure
2.printf();
printf: default line buffering
The following conditions will write the buffer's data to the screen:
1. Encounter the Enter key
2. The buffer is full
3. Manual refresh
4. The program ends
3.getpid();
get the parent process id;
4.getppid();
get the child process id;
5. Orphan process: a process whose child process has ended;
6. Zombie process: the child process is not recycled by the parent process, nor by the system kernel;
7.wait();
The parent process recycles the child process. If the child process has not ended, wait is a blocking function. After waiting for the child process to end, the parent process will recycle it;
8.system(): Execute other programs without affecting the current program, simple but inefficient;
Example: system ("ls -l, pwd, cat 1_fork.c"); also implement ls -l; pwd cat function;
9.exec(): Execute other programs, which will affect the current program
Clear all the data of the current program, and load the program data to be executed. Once the call is successful, the previous program cannot be returned.
thread
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine) (void *), void *arg);
Function function: create thread
Parameter Description:
pthread : outgoing the identifier of the newly created thread
attr: set thread attributes
start_routine: thread entry function
arg: pass arguments to the new thread
Return value: 0 for success, error number for failure
PS: Manually link to the thread library when compiling (gcc XX.c -o xx -lpthread)
pthread_join(): Recycle the thread, if the thread has not ended, block and wait;
pthread_exit(): thread ends;
pthread_detach( thread identifier): set the thread detach attribute;
Thread synchronization:
1. Define a mutex: pthread_mutex_t mutex;
2. Initialize the mutex:
int pthread_mutex_init(pthread_mutex_t *restrict mutex,
const pthread_mutexattr_t *restrict attr);
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
ps : Steps 1 and 2 are done before creating the thread!
3. Lock
int pthread_mutex_lock(pthread_mutex_t *mutex);
4. Unlock
int pthread_mutex_unlock(pthread_mutex_t *mutex);
5. Destroy the mutex
int pthread_mutex_destroy(pthread_mutex_t *mutex);
example:
#include <stdio.h> #include <pthread.h> #include <unistd.h> #include <string.h> char buff[1024]; pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;//manage buff void* pthread_task(void* argv) { sleep(1); while(1) { printf("lock...\n"); pthread_mutex_lock(&mutex); printf("lock over...\n"); strcpy(buff, "hello"); printf("buff: %s\n",buff); pthread_mutex_unlock(&mutex); sleep(1); } return NULL; } int main() { pthread_t pth; if(0 != pthread_create(&pth, NULL, pthread_task, NULL)) { perror("pthread_create"); return -1; } while(1) { pthread_mutex_lock(&mutex); strcpy(buff, "xiaoqixxxx"); printf("main pthread: %s\n",buff); pthread_mutex_unlock(&mutex); sleep(1); } pthread_mutex_destroy(&mutex); return 0; }
condition variable
1. Define condition variables and mutex locks, and initialize them (complete before creating threads)
2. Producers
(1) lock
(2) Operation of public resources
(3) Unlock
(4) Send a signal to all consumer threads blocked on the condition variable
3. Consumers
(1) lock
(2) while (no resources)
Call the wait function, block on the condition variable, and wait to be woken up
There are resources, direct consumption
(3) Unlock
Condition variable correlation function:
(0) Condition variable initialization
int pthread_cond_init(pthread_cond_t *restrict cond,
const pthread_condattr_t *restrict attr);
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
(1) Send signal function
int pthread_cond_broadcast(pthread_cond_t *cond);
int pthread_cond_signal(pthread_cond_t *cond);
(2) Blocking function
int pthread_cond_wait(pthread_cond_t *restrict cond,
pthread_mutex_t *restrict mutex);
ps: No resources, it will be unlocked, and then blocked waiting
If woken up, it will apply for a lock
#include <stdio.h> #include <pthread.h> #include <stdlib.h> #include <assert.h> #include <unistd.h> struct node { int data; struct node *next; }; pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; pthread_cond_t cond = PTHREAD_COND_INITIALIZER; struct node *head = NULL; void* producter(void *argv)//producer { struct node *pnew = NULL; while(1) { pnew = (struct node*)malloc(sizeof(struct node)); assert(pnew!=NULL); pnew->data = rand()%100; pnew->next = NULL; printf("-----product data: %d-----\n", pnew->data); pthread_mutex_lock(&mutex); pnew->next = head; head = pnew; pthread_mutex_unlock(&mutex); pthread_cond_broadcast(&cond); sleep(rand()%3); } return NULL; } void* consumer(void* argv) { struct node *pdel = NULL; while(1) { pthread_mutex_lock(&mutex); while(head == NULL) { pthread_cond_wait(&cond, &mutex); } pdel = head; head = head->next; printf("----consumer data: %d\n", pdel->data); free(pdel); pthread_mutex_unlock(&mutex); sleep(rand()%3); } return NULL; } int main() { pthread_t pth1, pth2; if( 0 != pthread_create(&pth1, NULL, producter, NULL)) { perror("pthread_create"); return -1; } if( 0 != pthread_create(&pth2, NULL, consumer, NULL)) { perror("pthread_create"); return -1; } pthread_join(pth1, NULL); pthread_join(pth2, NULL); return 0; }
file lock
Function: set file lock
Parameter Description:
fd : file descriptor
cmd : command
F_SETLKW : set file lock
struct flock {
...
short l_type; /* Type of lock: F_RDLCK,
F_WRLCK, F_UNLCK /
short l_whence; / How to interpret l_start:
SEEK_SET, SEEK_CUR, SEEK_END /
off_t l_start; / Starting offset for lock /
off_t l_len; / Number of bytes to lock */
...
};
Structure defined by the system kernel
#include <stdio.h> #include <unistd.h> #include <fcntl.h> int main() { int fd; fd = open("./data.txt", O_CREAT|O_WRONLY|O_TRUNC, 0777); if(fd < 0) { perror("open"); return -1; } struct flock fk; fk.l_type = F_WRLCK; fk.l_whence = SEEK_SET; fk.l_start = 0; fk.l_len = 100; fcntl(fd, F_SETLKW, &fk); write(fd, "hello", 5); sleep(20); fk.l_type = F_UNLCK; fcntl(fd, F_SETLKW, &fk); close(fd); return 0; }
ps: One of the two programs gets the file lock, then before unlocking, the other program will block and wait until the file lock is obtained;
message queue
nt msgget(key_t key, int msgflg);
Function: Create or get the identifier of the message queue
Parameter Description:
key : key value, a key value and a message queue have a one-to-one correspondence
msgflg: set flag, generally use IPC_CREAT|0777
return value:
Successfully returns the identifier of the message queue
return -1 on failure;
#include <stdio.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> int main() { int msgid; msgid = msgget(0x100, IPC_CREAT|0777); if(msgid < 0) { perror("msgget"); return -1; } return 0; }
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
Function: Send a message to the message queue
Parameter Description:
msqid: message queue identifier
msgp: The starting address of the packaged message information structure
msgsz: message size
msgflg: set blocking flag, 0 means blocking
return value:
Returns 0 on success, -1 on failure
struct msgbuf {
long mtype; /* message type, must be > 0 /
char mtext[1]; / message data */
};
#include <stdio.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> struct msgbuf { long mtype; char mtext[1024]; }; int main() { int msgid; msgid = msgget(0x100, IPC_CREAT|0777); if(msgid < 0) { perror("msgget"); return -1; } struct msgbuf mb = {2, "xiaoqi"}; msgsnd(msgid, &mb, 6, 0); return 0; }
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,
int msgflg);
Function: read data from the message queue
Parameter Description:
msqid : the identifier of the message queue
msgp: The starting address of the received message data structure
msgtype: message type
If the type is 0, read the first message by default
If the type is non-zero, start the search from the first message and read the message of the specified type
msgflg: set blocking flag, 0 means blocking
return value:
Returns the actual size read on success, -1 on failure
#include <stdio.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> struct msgbuf { long mtype; char mtext[1024]; }; int main() { int msgid; msgid = msgget(0x100, IPC_CREAT|0777); if(msgid < 0) { perror("msgget"); return -1; } struct msgbuf mb; int ret; ret = msgrcv(msgid, &mb, 1024, 5, 0); printf("Ret = %d\n", ret); mb.mtext[ret] = '\0'; printf("mtext: %s\n", mb.mtext); return 0; }
Shared memory
int shmget(key_t key, size_t size, int shmflg);
Function: Create shared memory
Parameter Description:
key : key value
size : memory size
shmflg: set flag IPC_CREAT|0777
return value:
Successfully returns the identifier of the shared memory
return -1 on failure
#include <sys/ipc.h> #include <sys/shm.h> #include <stdio.h> int main() { int shmid; shmid = shmget(0x200, 100, IPC_CREAT|0777); if(shmid < 0) { perror("shmget"); return -1; } return 0; }
void *shmat(int shmid, const void *shmaddr, int shmflg);
Function: Map shared memory into the program
Parameter Description:
shmid : shared memory identifier
shmaddr: specify the mapping address, generally use NULL, specified by the system
shmflg: set flag, generally use 0
return value:
Successfully returns the mapped virtual address
Returns (void*)-1 on failure
#include <sys/ipc.h> #include <sys/shm.h> #include <stdio.h> #include <string.h> struct student { int num; char name[32]; }; int main() { int shmid; shmid = shmget(0x200, 100, IPC_CREAT|0777); if(shmid < 0) { perror("shmget"); return -1; } struct student *ps = shmat(shmid, NULL, 0); struct student s1 = {1001, "zhangsan"}; memcpy(ps, &s1, sizeof(struct student)); printf("%d\t%s\n", ps->num, ps->name); return 0; }
function pointers (emphasis)
#include <stdio.h> typedef void (*pFun)() ; //Aliases for function pointer types void func() { printf("hello world\n"); } int main() { //void (*pfun)() = func; //pfun function pointer variable //pfun(); pFun p = func; p(); return 0; }
Signal
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
Function function: Register signal processing function
Parameter Description:
signum : signal value
handler : function entry address
SIG_IGN: ignore signal
SIG_DFL: perform default action
#include <stdio.h> #include <signal.h> #include <unistd.h> void hangle(int sig) { printf("recv sig: %d\n", sig); } int main() { //signal(SIGUSR2, hangle); //signal(SIGINT, hangle); signal(SIGSEGV, hangle); char *p = NULL; *p = 90; while(1) { sleep(1); printf("."); fflush(stdout); } return 0; }
send a signal to a process
#include <stdio.h> #include <sys/types.h> #include <signal.h> #include <stdlib.h> int main(int argc, char*argv[]) { if(argc < 2) { printf("Missing parameters!\n"); return -1; } int pid ; pid = atoi(argv[1]); kill(pid, 9); return 0; }