System Programming (I/O)

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;
}

Tags: C++ C# network

Posted by dsp77 on Sun, 04 Sep 2022 08:27:48 +0300